从XML解析后,JAXB Unmarshaller在对象中返回null

时间:2018-07-16 09:20:40

标签: java xml-parsing jaxb unmarshalling pojo

我有一个带有xml数据的String对象。 我想要POJO中的数据,我尝试使用JAXB unmarshaller进行转换,但它始终为我提供对象属性中的空值。

这是我的代码:

ResponseEntity<String> response = restTemplate.getForEntity("https://api.flickr.com/services/rest/?api_key=MY_API_KEY&method=flickr.photos.search&tags=nature", String.class);    
String resp = response.getBody();

JAXBContext jaxBcontext = JAXBContext.newInstance(Resp.class);
Unmarshaller unmarshaller = jaxBcontext.createUnmarshaller();
Resp respObj = (Resp)unmarshaller.unmarshal(new StringReader(resp));

字符串中的值是:

 <rsp stat="ok">
 <photos page="1" pages="4226" perpage="100" total="422597">
 <photo id="28534349567" owner="79805131@N08" secret="b8bd7fe7cb" 
 server="843" farm="1" title="Savoie S006." ispublic="1" isfriend="0" 
 isfamily="0"/>
 <photo id="43355895332" owner="155237230@N05" secret="75fd48d040" 
 server="1769" farm="2" title="IMG_3139" ispublic="1" isfriend="0" 
 isfamily="0"/>
 <photo id="41595746070" owner="125407841@N08" secret="1f216ab8b8" 
 server="1822" farm="2" title="" ispublic="1" isfriend="0" isfamily="0"/>
 </photos>
 </rsp>

POJOS是:

 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlRootElement(name = "rsp")
 public class Resp {

    @XmlElement(name="stat")
    private String stat;

    @XmlElement(name="photos" , type = Photos.class)
    private Photos photos;

    public String getStat() {
        return stat;
    }
    //constructors and getter setters

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "photos")
public class Photos {

    @XmlElement(name="total")
    private String total;

    @XmlElement(name="page")
    private String page;

    @XmlElement(name="pages")
    private String pages;

    @XmlElement(name="perpage")
    private String perpage;

    @XmlElement(name="photo" , type=Photo.class)
    private List<Photo> photoObject = new ArrayList<Photo>();

    // constructors and getter setters.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "photo")
public class Photo {

    @XmlElement(name="id")
    private String id;

    @XmlElement(name="isfamily")
    private String isfamily;

    @XmlElement(name="title")
    private String title;

    @XmlElement(name="ispublic")
    private String ispublic;

    @XmlElement(name="owner")
    private String owner;

    @XmlElement(name="secret")
    private String secret;

    @XmlElement(name="server")
    private String server;

    @XmlElement(name="isfriend")
    private String isfriend;

    // constructors and setter getter

我得到的响应在所有这些对象中均为空值。

分别[stat = null,photos =照片[total = null,page = null,pages = null,    perpage = null,照片=]]

我得到的String中的值是绝对正确的,但是当我尝试将数据映射到POJO时,它将开始出现错误。

其他方法,如我在其他问题中提到的那样,我用它来直接在对象中获取数据,但是它也存在一些问题。

RestTemplate returns data in String but not populate list nested objects

如果任何人都可以提供帮助,那将是有帮助的。

2 个答案:

答案 0 :(得分:0)

由于@ f1sh已经评论, 您的问题是由您的POJO类中的几个问题引起的

  • 在XML响应中,您有 .handle(httpRequestExecutingMessageHandler())(即<rsp stat="ok">...</rsp>是XML属性) 而不是stat<rsp><stat>ok</stat>...</rsp>是XML元素)。
    因此,在您的stat类中,Resp属性需要用 stat而非@XmlAttribute
  • 出于同样的原因,在您的@XmlElement类中,所有属性 Photos属性需要加上注释 photoObject而非@XmlAttribute
  • 出于同样的原因,在您的@XmlElement类中,所有属性 需要使用Photo而不是@XmlAttribute进行注释。

要考虑的更多最佳做法:

  • @XmlElementPhotos类中,您可以删除Photo批注 因为这些不是根本要素。 只有@XmlRootElement类是根元素,因此需要Resp
  • 在您的@XmlRootElement类中,应将Photos属性重命名为photoObject (带有多个 s ),因为它是一个列表。这将使代码更易于理解。

答案 1 :(得分:0)

我找到了解决方法。

需要将注解@XMLAttribute和@XmlElements放在setter上。

不适用于吸气剂和声明。