xml patch请求体须为无声明的合法xml片段,content-type必须设为application/xml,服务端依xpath或rfc规范解析,客户端需避免jaxb默认全字段序列化。

XML PATCH 请求体必须是合法的 XML 片段,不是完整文档
RESTful API 的 PATCH 方法要求只传需要修改的字段,但 XML 没有像 JSON 那样天然支持“局部更新”的语法。服务端通常依赖 XPath 或自定义语义解析这个片段——所以你发的不能是带 <?xml version="1.0"?> 的完整文档,也不能缺根元素(哪怕只是包装用的)。
常见错误现象:400 Bad Request 或 422 Unprocessable Entity,日志里出现 “root element missing” 或 “invalid XML structure”。
- 用
<user><email>new@example.com</email></user>,而不是<?xml...><user>...</user> - 如果 API 文档指定了补丁格式(比如 RFC 7396 的
application/merge-patch+xml),必须严格遵循其结构,否则服务端会拒绝 - 某些后端框架(如 Spring Web MVC)默认不支持 XML PATCH 解析,需手动注册
Jaxb2RootElementHttpMessageConverter并启用@RequestBody对 XML 片段的绑定
HTTP 头必须显式声明 Content-Type: application/xml
很多开发者习惯性沿用 application/json 的思路,漏掉或错写这个头,结果服务端把 XML 当成纯文本或尝试用 JSON 解析器处理,直接 415 错误。
使用场景:curl、Postman、axios、fetch 都要手动设置;Spring Boot 的 RestTemplate 默认不设这个头,需调用 setHeader("Content-Type", "application/xml")。
- 不要用
text/xml—— 它不表示可执行更新,部分 API 会拒绝 - 如果服务端要求带字符编码,写成
application/xml;charset=UTF-8,注意UTF-8不要加引号 - GET 请求没这问题,但 PATCH 必须有;HEAD/OPTIONS 也不需要
PATCH 和 PUT 在 XML 更新中语义完全不同
PUT 是全量替换:你传什么,资源就变成什么,哪怕只传一个字段,其他字段也会被清空或重置为默认值。PATCH 才是真正的局部更新——但前提是服务端实现了字段级合并逻辑。
性能影响:PUT 可能触发整行数据库更新 + 全字段校验;PATCH 通常只更新指定列,但需要服务端做差异比对,可能更耗 CPU。
- 传
<user><status>active</status></user>到PATCH /api/users/123,应只改status字段 - 同一请求里重复字段(如两个
<email></email>)会导致未定义行为,多数服务端取第一个,少数报错 - 没有标准规定 XML PATCH 如何处理缺失字段——是忽略?置空?还是保留原值?必须查清服务端文档或试出来
Java/Spring Boot 调用时,JAXB 默认不支持部分绑定
你写个 UserPatch 类只含 email 和 status 字段,用 JAXBContext.newInstance(UserPatch.class) 序列化,看似合理,但 JAXB 默认会把所有字段序列化为空标签(如 <name></name>),导致 PATCH 请求意外清空字段。
容易踩的坑:没关 XmlAccessorType(XmlAccessType.NONE),或忘了给字段加 @XmlElement,结果生成的 XML 包含了你不想要的字段。
- 必须加
@XmlAccessorType(XmlAccessType.FIELD)或PROPERTY,并只标注要发送的字段 - 字段设为
null后,JAXB 默认不输出该标签;但如果字段类型是基本类型(int、boolean),无法为 null,得换包装类或用@XmlElement(nillable = true) - Spring 的
@RequestBody接收 XML PATCH 时,建议用org.w3c.dom.Document或String原始接收,再用 XPath 提取,比强转 POJO 更可控










