首页 > 解决方案 > 从 XML 解析后,JAXB Unmarshaller 在对象中返回 null

问题描述

我有一个带有 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

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

Resp [stat=null, photos=Photos [total=null, page=null, pages=null, perpage=null, photo=]]

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

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

RestTemplate 以 String 形式返回数据,但不填充列表嵌套对象

如果有人可以在其中任何一个方面提供帮助,那将很有帮助。

标签: javaxml-parsingjaxbunmarshallingpojo

解决方案


As @f1sh already already commented, your problems are caused by several issues within your POJO classes

  • In your XML response you have <rsp stat="ok">...</rsp> (i.e. statis an XML attribute) instead of <rsp><stat>ok</stat>...</rsp> (statbeing an XML element).
    Therefore, in your Resp class the statproperty needs to annotated with @XmlAttribute instead of @XmlElement.
  • For the same reason, in your Photos class, all properties except for the photoObjectproperty need to be annotated with @XmlAttribute instead of @XmlElement.
  • For the same reason, in your Photo class all properties need to be annotated with @XmlAttribute instead of @XmlElement.

Some more best practices to consider:

  • In your Photos and Photo classes you can remove the @XmlRootElement annotation because theses are not root elements. Only the Resp class is a root element and therefore needs @XmlRootElement.
  • In your Photos class you should rename the photoObject property to photoObjects (with a plural s) because it is a list. This would make the code easier to understand.

推荐阅读