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

如何在Retrofit中使用JAXB替代SimpleXml?求迁移实现指南

我刚帮几个朋友搞定过Retrofit从Simple XML到JAXB的迁移,给你整理了一份超实用的快速指南,一步步来完全没压力:

从Simple XML Framework迁移到JAXB(Retrofit 2.4.0+)

第一步:替换依赖

首先把项目里的SimpleXml转换器依赖换成JAXB的:

Gradle配置

原来的SimpleXml依赖:

implementation 'com.squareup.retrofit2:converter-simplexml:2.4.0'

替换成JAXB转换器:

implementation 'com.squareup.retrofit2:converter-jaxb:2.4.0'

注意:如果你的项目用的是Java 9+,可能需要额外添加JAXB API依赖(Java 9开始JAXB不再是JDK默认包含的部分):

implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'com.sun.xml.bind:jaxb-core:2.3.0.1'
implementation 'com.sun.xml.bind:jaxb-impl:2.3.2'

Maven配置

原来的:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-simplexml</artifactId>
    <version>2.4.0</version>
</dependency>

替换成:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-jaxb</artifactId>
    <version>2.4.0</version>
</dependency>

第二步:替换POJO中的注解

这是迁移的核心,把SimpleXml的注解一一对应换成JAXB的,下面是最常用的映射表:

SimpleXml注解JAXB对应注解备注说明
@Root(name = "xxx")@XmlRootElement(name = "xxx")标记XML根元素
@Element(name = "xxx")@XmlElement(name = "xxx")标记普通XML元素
@ElementList(inline = true)@XmlElement(name = "xxx")当inline=true时,不需要包装节点,直接用@XmlElement标记列表;如果需要包装器,用@XmlElementWrapper(name = "xxx") + @XmlElement(name = "item")
@Attribute(name = "xxx")@XmlAttribute(name = "xxx")标记XML属性
@Transient@XmlTransient忽略字段,不参与序列化/反序列化
@Text@XmlValue标记文本内容节点
@Namespace@XmlRootElement(namespace = "xxx")处理命名空间,也可在包级别通过package-info.java全局配置

示例对比

原来的SimpleXml POJO:

@Root(name = "user")
public class User {
    @Attribute(name = "id")
    private int userId;
    
    @Element(name = "name", required = false)
    private String userName;
    
    @ElementList(name = "posts", inline = true)
    private List<Post> userPosts;
}

迁移后的JAXB POJO:

@XmlRootElement(name = "user")
public class User {
    @XmlAttribute(name = "id")
    private int userId;
    
    @XmlElement(name = "name", required = false)
    private String userName;
    
    @XmlElement(name = "posts") // 对应inline=true,直接标记列表元素
    private List<Post> userPosts;
}

第三步:修改Retrofit配置

把原来的SimpleXml转换器工厂换成JAXB的:

原来的代码:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://your-api-url.com/")
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .build();

修改后的代码:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://your-api-url.com/")
    .addConverterFactory(JaxbConverterFactory.create())
    .build();

第四步:注意事项与特殊场景

  1. 空值处理:JAXB默认会忽略null字段不生成元素,和SimpleXml的@Element(required=false)行为一致;如果需要强制生成空元素,可以添加@XmlElement(nillable = true)。
  2. 多态/继承处理:如果原来用了SimpleXml的多态特性,JAXB需要在父类上添加@XmlSeeAlso({SubClass1.class, SubClass2.class})来声明子类,确保序列化/反序列化正常识别。
  3. 自定义转换逻辑:如果原来有自定义的SimpleXml转换器,需要换成JAXB的XmlAdapter,实现XmlAdapter<ValueType, BoundType>接口,然后用@XmlJavaTypeAdapter(YourAdapter.class)标记对应的字段。
  4. 全局命名空间配置:如果需要统一配置命名空间,可以在包下创建package-info.java文件:
    @XmlSchema(
        namespace = "http://your-namespace.com",
        elementFormDefault = XmlNsForm.QUALIFIED
    )
    package com.your.package;
    
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;
    

最后一步:测试验证

跑一遍你的接口调用,重点检查列表、属性、空值这些容易出问题的场景,确保XML的序列化和反序列化结果和之前一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:37:18