2012-04-01 60 views
1

我試圖將Json結果從Web服務反序列化爲POJO。如何使用Restlet將Json結果反序列化爲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爲空,不會引發異常。
我是新來的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類竟被d是要大到在這裏張貼,但我已儘可能合理地繪製了元素。

+0

我認爲你的意思是deserilize?至於你的映射,我認爲應該至少拋出一個異常,但是馬上就好像你期望專輯列表映射到「結果」JSON節點,但是沒有任何東西可以使這種關聯。可以使用log4j將異常記錄到其他地方嗎? – 2012-04-01 18:22:53

+0

是的,你是對的。但是,我怎樣才能將Json「結果」映射到我的課堂上呢? – 2012-04-01 18:37:22

回答

0

嘗試使用JAXB annotations或使用Jersey進行JSON映射。本手冊可能對您有用:link

1

注:我是EclipseLink JAXB (MOXy)鉛和JAXB 2 (JSR-222)專家小組的成員。

下面是它如何與莫西通過利用JAXB註釋來完成:

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

要指定莫西爲您的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" 
    } ] 
} 

更多信息

2

如果你還沒有,你需要的Restlet的JacksonConverter添加到已註冊轉換器的列表:

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

一個d,當然,將org.restlet.ext.jackson.jar添加到您的構建路徑中。

0

最近我不得不開發一個帶有Restlet框架的Android應用程序,我花了很多時間來理解如何反序列化一個JSONObject。 在這裏,我將解釋我的方法。 我還出版了一本完整的Android應用程序在GitHub上的位置:
https://github.com/alchimya/android-restlet

的Restlet 2.3.2包括GSON庫。使用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)用列表屬性創建一個類:

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); 

進入response.results您的資源將會有所有的反序列化項目。