You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring REST控制器无法处理含转义HTML的XML负载问题排查

问题:XML负载中的转义字符导致Spring控制器请求参数拆分/截断

我正在开发一个Spring控制器,作为我方无法控制的第三方平台的事件订阅者。当该平台创建或更新内容时,会向指定回调URL发送POST请求,请求包含变更信息(含内容主体)。但控制器接收请求时,XML负载中的转义HTML字符导致文档被破坏,进而引发XML解析问题。

简化后的控制器代码

@RestController
public class Controller {

  @PostMapping(path = "/listenerOne")
  public ResponseEntity<String> listenerOne(
      @RequestParam(name = "event.type") final String eventType,
      @RequestParam(name = "message", required = false) final String xmlPayload) {
    return ResponseEntity.ok().body(xmlPayload);
  }

  @PostMapping(path = "/listenerTwo", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
  public ResponseEntity<String> listenerTwo(@RequestBody final MultiValueMap<String, String> messageEvent) {
    return ResponseEntity.ok().body(messageEvent.toString());
  }

}

请求参数示例(message-event.xml)

<message type="message" href="/messages/id/1313133">
    <body type="string">&lt;P&gt;Test body&lt;/P&gt;</body>
    <subject type="string">Test message</subject>
    <id type="int">1313133</id>
</message>

测试curl命令及结果

测试/listenerOne

curl -XPOST localhost:8080/listenerOne -d "event.type=MessageUpdate&message=$(cat message-event.xml)"

返回结果:

<message type="message" href="/messages/id/1313133">
    <body type="string">%

测试/listenerTwo

curl -XPOST localhost:8080/listenerTwo -d "event.type=MessageUpdate&message=$(cat message-event.xml)"

返回结果:

{event.type=[MessageUpdate], message=[<message type="message" href="/messages/id/1313133">
    <body type="string">], lt;P=[], gt;Test body=[], lt;/P=[], gt;</body>
    <subject type=["string">Test message</subject>
    <id type="int">1313133</id>
</message>]}%

可见<body type="string">之后的内容被截断或拆分,请问为何会出现请求体/参数拆分的情况?


原因分析

问题核心在于**application/x-www-form-urlencoded格式的参数解析规则冲突**:

  1. URL编码规则的影响
    application/x-www-form-urlencoded格式要求参数值中的特殊字符(如&、=、%)必须做URL编码。而XML里的&lt;是XML转义字符,但在URL编码语境下,&是参数分隔符。当未编码的&出现在参数值中时,会被解析成参数分隔符,导致原本属于message参数的内容被拆分成多个无效参数:
  • message参数只拿到<body type="string">部分
  • 后续的lt;P、gt;Test body等被误判为新的空值参数
  1. curl命令的直接拼接问题
    你用$(cat message-event.xml)直接将XML内容插入curl的-d参数中,curl会把XML里的&当作参数分隔符处理,而非message参数值的一部分,这直接引发了参数截断和拆分。

  2. Spring的参数解析逻辑
    Spring处理application/x-www-form-urlencoded请求时,会严格遵循URL编码规则拆分参数。一旦遇到未编码的&,就会判定为新参数的起始点,自然会把原message参数的内容拆解得支离破碎。


内容的提问来源于stack exchange,提问作者Steven Spasbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:27:14