使用Spring的PageAdapter时遇XML类型名冲突问题
解决JAXB中两个ResourceSupport类的XML类型名冲突问题
你碰到的是JAXB类型命名冲突的典型场景——两个不同包下的ResourceSupport类(自定义的com.x.y.rest.data.ResourceSupport和Spring HATEOAS的org.springframework.hateoas.ResourceSupport)默认生成了相同的XML类型名resourceSupport,导致JAXB无法区分它们。修改Filter类的@XmlType没用,是因为冲突的根源不在Filter本身,而在这两个ResourceSupport类上。
下面是几种可行的解决方案,适配你无法修改ItemView的限制:
1. 给自定义的ResourceSupport添加@XmlType注解
直接修改你项目中自定义的com.x.y.rest.data.ResourceSupport类,给它指定唯一的XML类型名和命名空间:
import javax.xml.bind.annotation.XmlType; @XmlType(name = "customResourceSupport", namespace = "http://your.project.namespace/rest") public class ResourceSupport { // 你的类代码 }
这样JAXB会为这个类生成独特的XML类型标识,和Spring HATEOAS的ResourceSupport彻底区分开。
2. 使用JAXB外部绑定文件重命名冲突类型
如果无法修改自定义ResourceSupport的代码,可以通过外部绑定文件(binding.xml)来配置类型别名:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"> <!-- 重命名自定义的ResourceSupport --> <jaxb:bindings packageName="com.x.y.rest.data"> <jaxb:bindings className="ResourceSupport"> <jaxb:class name="customResourceSupport" namespace="http://your.custom.namespace"/> </jaxb:bindings> </jaxb:bindings> <!-- 可选:也可以给Spring的ResourceSupport重命名,确保万无一失 --> <jaxb:bindings packageName="org.springframework.hateoas"> <jaxb:bindings className="ResourceSupport"> <jaxb:class name="springHateoasResourceSupport" namespace="http://spring.io/hateoas"/> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
之后在初始化JAXB上下文时指定这个绑定文件,比如在Spring的Jaxb2Marshaller中配置:
@Bean public Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setPackagesToScan("com.x.y.z.e.domain.m", "org.springframework.data.domain.jaxb"); marshaller.setBindings(new ClassPathResource("binding.xml")); return marshaller; }
3. 自定义JAXB上下文的类型别名
通过Spring的Jaxb2Marshaller直接设置类型别名,强制给两个冲突类分配不同的XML名称:
import org.springframework.oxm.jaxb.Jaxb2Marshaller; import java.util.HashMap; import java.util.Map; @Bean public Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setPackagesToScan("com.x.y.z.e.domain.m", "org.springframework.data.domain.jaxb"); Map<String, Class<?>> typeAliases = new HashMap<>(); typeAliases.put("customResourceSupport", com.x.y.rest.data.ResourceSupport.class); typeAliases.put("springResourceSupport", org.springframework.hateoas.ResourceSupport.class); marshaller.setTypeAliases(typeAliases); return marshaller; }
这种方式不需要修改任何实体类代码,完全通过配置解决冲突。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

