繁体   English   中英

如何使用Restlet将Json结果反序列化为POJO

[英]How to deserialize Json result into POJO using Restlet

我正在尝试将Json结果从Web服务反序列化为POJO。

ClientResource clientResource = new ClientResource("http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album");
AlbumInfoResource resource = clientResource.wrap(AlbumInfoResource.class);
AlbumInfo albumInfo = resource.retrieve();

生成的albumInfo为null,不会抛出异常。
我是Restlet的新手,我做错了什么?

接口:

public interface AlbumInfoResource {
  @Get
  public AlbumInfo retrieve();
 }

Web服务的Json结果如下所示:

{
    "resultCount": 49,
    "results": [
        {
            "wrapperType": "collection",
            "collectionType": "Album",
            "artistId": 771969,
            "collectionId": 205639995,
            "amgArtistId": 4640,
            "artistName": "Marc Jordan",
            "collectionName": "This Is How Men Cry",
            "collectionCensoredName": "This Is How Men Cry",
            "artistViewUrl": "http://itunes.apple.com/us/artist/marc-jordan/id771969?uo=4",
            "collectionViewUrl": "http://itunes.apple.com/us/album/this-is-how-men-cry/id205639995?uo=4",
            "artworkUrl60": "http://a5.mzstatic.com/us/r30/Music/cd/3f/13/mzi.rxpvpvdd.60x60-50.jpg",
            "artworkUrl100": "http://a1.mzstatic.com/us/r30/Music/cd/3f/13/mzi.rxpvpvdd.100x100-75.jpg",
            "collectionPrice": 9.9,
            "collectionExplicitness": "notExplicit",
            "trackCount": 10,
            "copyright": "1999 Cafe Productions Inc.",
            "country": "USA",
            "currency": "USD",
            "releaseDate": "2006-11-07T08:00:00Z",
            "primaryGenreName": "Jazz"
        },
...
...
    }
]

}

AlbumInfo类:

public class AlbumInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    private int _resultCount;
    private ArrayList<Album> _albums;

    public AlbumInfo() {
        _albums = new ArrayList<Album>();
    }

    public AlbumInfo(int resultCount, ArrayList<Album> albums) {
        _resultCount = resultCount;
        _albums = albums;
    }

    public int getResultCount() {
        return _resultCount;
    }

    public void setResultCount(int resultCount) {
        _resultCount = resultCount;
    }

    public ArrayList<Album> getAlbums() {
        return _albums;
    }

    public void setAlbums(ArrayList<Album> _albums) {
        this._albums = _albums;
    }

}

Album类在这里发布很大,但我已尽可能合理地映射元素。

如果您还没有,则需要将Restlet的JacksonConverter添加到已注册的转换器列表中:

    List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters();
    converters.add(new JacksonConverter());

当然,将org.restlet.ext.jackson.jar添加到您的构建路径中。

注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB 2(JSR-222)专家组的成员。

以下是如何通过利用JAXB注释使用MOXy来完成的:

AlbumInfo

package forum9966753;

import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.*;

@XmlType(propOrder={"resultCount", "albums"})
public class AlbumInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    private int _resultCount;
    private ArrayList<Album> _albums;

    public AlbumInfo() {
        _albums = new ArrayList<Album>();
    }

    public AlbumInfo(int resultCount, ArrayList<Album> albums) {
        _resultCount = resultCount;
        _albums = albums;
    }

    public int getResultCount() {
        return _resultCount;
    }

    public void setResultCount(int resultCount) {
        _resultCount = resultCount;
    }

    @XmlElement(name="results")
    public ArrayList<Album> getAlbums() {
        return _albums;
    }

    public void setAlbums(ArrayList<Album> _albums) {
        this._albums = _albums;
    }

}

专辑

以下是您的Album类的缩小版:

package forum9966753;

public class Album {

    private String wrapperType;

    public String getWrapperType() {
        return wrapperType;
    }

    public void setWrapperType(String wrapperType) {
        this.wrapperType = wrapperType;
    }

}

jaxb.properties

要将MOxy指定为JAXB提供程序,您需要在与域类相同的包中添加名为jaxb.properties的文件,并使用以下条目:

javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory

演示

package forum9966753;

import java.io.InputStream;
import java.net.*;
import java.util.List;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.example.Customer;

public class JavaSEClient {

    private static final String MEDIA_TYPE = "application/json";

    public static void main(String[] args) throws Exception {
        String uri = "http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album";
        URL url = new URL(uri);
        HttpURLConnection connection =
            (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Accept", MEDIA_TYPE);

        JAXBContext jc = JAXBContext.newInstance(AlbumInfo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", MEDIA_TYPE);
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        InputStream xml = connection.getInputStream();
        AlbumInfo albumInfo = unmarshaller.unmarshal(new StreamSource(xml), AlbumInfo.class).getValue();
        connection.disconnect();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", MEDIA_TYPE);
        marshaller.setProperty("eclipselink.json.include-root", false);
        marshaller.marshal(albumInfo, System.out);
    }

}

产量

以下是运行演示代码的输出。 由于示例域模型仅包含一些属性,因此输出远小于输出。 可以轻松应用JAXB映射来映射文档的其余部分。

{
   "resultCount" : 49,
   "results" : [ {
      "wrapperType" : "collection"
   } ]
}

欲获得更多信息

最近我不得不开发一个带有Restlet框架的Android应用程序,我花了很多时间来了解如何反序列化JSONObject。 在这里,我将解释我的方法。 我还在GitHub上发布了一个完整的Android应用程序:
https://github.com/alchimya/android-restlet

Restlet 2.3.2包含Gson lib。 使用Gson可以非常简单地映射和反序列化资源。

1)使用以下类映射您的实体库:

import com.google.gson.annotations.SerializedName;
import java.io.Serializable;

public class Album implements Serializable {

    @SerializedName("wrapperType")
    private String wrapperType;

    @SerializedName("collectionType")
    private String collectionType;

    @SerializedName("artistId")
    private String artistId;

    public String getWrapperType() {
        return wrapperType;
    }
    public void setWrapperType(String wrapperType) {
        this.wrapperType = wrapperType;
    }

    public String getCollectionType() {
        return collectionType;
    }
    public void setCollectionType(String collectionType) {
        this.collectionType = collectionType;
    }

    public String getArtistId() {
        return artistId;
    }
    public void setArtistId(String artistId) {
        this.artistId = artistId;
    }

    ......
    ......
    ......
}

注意:在上一个类中,每个属性都有一个注释(@SerializedName)来映射相应的JSON字段。 有关更多信息,请参阅本教程:
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html

2)创建一个具有List属性的类:

public class Albums {
    public List<Album> results;
}

3)使用Restlet消耗您的资源

String uri="http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album";

ClientResource resource = new ClientResource(url);
Representation rep = resource.get();

JsonRepresentation represent = new JsonRepresentation(rep);
JSONObject jsonobject = represent.getJsonObject();
String jsonText = jsonobject.toString();

Gson gson = new Gson();
Albums response = gson.fromJson(jsonText, Albums.class);

响应。结果将有所有反序列化的项目。

尝试使用JAXB annotations或使用Jersey进行JSON映射。 本手册对您有用: 链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM