关于使用JAXB读取xml文档转换为java对象报错:类的两个属性具有相同名称com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsExc...

java 类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.demo;
 
import feign.Headers;
import feign.RequestLine;
import lombok.Data;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
public interface PersonClient {
 
    @RequestLine("POST /person/createXML")
    @Headers("Content-Type: application/xml")
    Result createPersonXML(Person person);
 
    @Data
    @XmlRootElement
    class Person {
        @XmlElement
        Integer personId;
        @XmlElement
        String personName;
        @XmlElement
        int personAge;
        @XmlElement
        String message;
    }
 
    @Data
    @XmlRootElement
    class Result {
        @XmlElement
        String message;
    }
}

  

错误如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Exception in thread "main" feign.codec.EncodeException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 4 counts of IllegalAnnotationExceptions
类的两个属性具有相同名称 "message"
    this problem is related to the following location:
        at public java.lang.String com.example.demo.PersonClient$Person.getMessage()
        at com.example.demo.PersonClient$Person
    this problem is related to the following location:
        at java.lang.String com.example.demo.PersonClient$Person.message
        at com.example.demo.PersonClient$Person
类的两个属性具有相同名称 "personAge"
    this problem is related to the following location:
        at public int com.example.demo.PersonClient$Person.getPersonAge()
        at com.example.demo.PersonClient$Person
    this problem is related to the following location:
        at int com.example.demo.PersonClient$Person.personAge
        at com.example.demo.PersonClient$Person
    同以上报错,此处省略....
    at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at feign.jaxb.JAXBContextFactory.getContext(JAXBContextFactory.java:74)
    at feign.jaxb.JAXBContextFactory.createMarshaller(JAXBContextFactory.java:56)
    at feign.jaxb.JAXBEncoder.encode(JAXBEncoder.java:58)
    ... 6 more

  

原因: 类中有两个相同的属性名,说明会同时访问 getter 方法和成员变量。
解决办法:
在类上加上@XmlAccessorType(XmlAccessType.FIELD)注解,加上此注解后,xml 的访问类型为成员变量,而不是 getter/setter 方法对。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.demo;
 
import feign.Headers;
import feign.RequestLine;
import lombok.Data;
 
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
public interface PersonClient {
 
    @RequestLine("POST /person/createXML")
    @Headers("Content-Type: application/xml")
    Result createPersonXML(Person person);
 
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    @XmlRootElement
    class Person {
        @XmlElement
        Integer personId;
        @XmlElement
        String personName;
        @XmlElement
        int personAge;
        @XmlElement
        String message;
    }
 
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    @XmlRootElement
    class Result {
        @XmlElement
        String message;
    }
}