2017-01-18 54 views
2

我正在用JAX-RS構建Java REST應用程序。Java REST反序列化列表

在應用程序的情況下,我有以下bean類:

public class ContentView { 
    // Field definitions, getters/setters 
} 

public class ArticleDetailView extends ContentView { 
    // more definitions, getters/setters 
} 

public class UpsellDetailView extends ContentView { 
    // more definitions, getters/setters 
} 

UpsellDetailView和ArticleDetailView有更多的屬性,它們都擴展內容查看。我已經正確連接了所有映射器,因此每個相應類的所有實例都可以正確設置其所有屬性。我不使用任何額外的映射器 - 對象屬性基於相應的bean類中的公共getter進行反序列化。

SeriesDetailView是相似的:

public class SeriesDetailView extends SeriesLiteView { 
    private List<Content> content; 

    @JsonIgnore //We don't want content appear on the Series detail page 
    public List<Content> getContent() { 
     return content; 
    } 

    public void setContent(List<Content> content) { 
     this.content = content; 
    } 
} 

現在,我有一個REST資源類,如下所示:

@Produces({MediaType.APPLICATION_JSON}) 
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED}) 
@Path("/") 
public class ApiSiteResource extends AbstractContentResource { 
... 
    @GET 
    @Path("/series/{uuid}/contents") 
    public List<ContentView> getSessionsForSeries(@Context HttpServletRequest request, @Context HttpServletResponse response, @BeanParam ApiParams params) { 
     final SeriesDetailView series = seriesService.findByUuid(params.getUuid()); 
     if (series == null) { 
      response.setStatus(SC_NOT_FOUND); 
      return null; 
     } 
     List<ContentView> contentViewList = contentMapper.map(series.getContent()); 
     List<ContentView> results = contentViewList.stream().map(e -> mapContent(e, e.getUuid())).collect(Collectors.toList()); 
     return results; 
    } 

    @GET 
    @Path("/contents/{uuid}") 
    public ContentView uniqueContent(@Context HttpServletRequest request, @Context HttpServletResponse response, @BeanParam ApiParams params) { 
     ContentView beanView = contentService.findByUuid(params.getUuid()); 
     if (beanView == null) { 
      response.setStatus(SC_NOT_FOUND); 
      return null; 
     } 
     beanView = mapContent(beanView, params.getUuid()); 
     return beanView; 
    } 

    private ContentView mapContent(ContentView beanView, String uuid){ 
     if (ArticleType.TypeGroup.upsell.toString().equals(beanView.getType())) { 
      UpSell upsell = ((UpSell)contentService.findByUuidRaw(uuid)); 
      beanView = (UpsellDetailView)upsellMapper.map(upsell); 
      rewriteBodyHtml(beanView, upsell.getBody()); 
     } 
     else if (ArticleType.TypeGroup.article.toString().equals(beanView.getType()) || 
       ArticleType.TypeGroup.audio.toString().equals(beanView.getType()) || 
       ArticleType.TypeGroup.video.toString().equals(beanView.getType())) { 
      Article article = ((Article)contentService.findByUuidRaw(uuid)); 
      beanView = (ArticleDetailView)articleMapper.map(article); 
      rewriteBodyHtml(beanView, article.getBody()); 
     } 
     return beanView; 
    } 
} 

現在,這裏的問題:

當調用/內容/ { uuid}在瀏覽器中,我得到完全反序列化正確的內容類型json(Article或UpsellDetailView),但是

當我調用/ series/{uuid}/contents時,我得到了一個與ContentView結構相對應的短形式json元素列表。

我確認List結果getSessionsForSeries()是正確類型的列表(Article或UpsellDetailView)。

但我無法找到我的生活爲什麼這些在列表中沒有得到正確的反序列化。我錯過了什麼?

+0

您可以包括請問「SeriesDetailView」類代碼?我看到你在「getSessionsForSeries」函數 - > –

+0

@SaifMasadeh中增加了結果,謝謝 –

+0

我看到你正在將結果上傳到「getSessionsForSeries」函數 - >列表結果我認爲這就是爲什麼你在「uniqueContent」中獲得結果的簡短版本時,你正在降低結果。 –

回答

1

這裏的答案:

出於某種原因,名單的串行一塌糊塗和序列化被默認爲聲明的內容類(內容查看)的時候了。

如果有人有一個想法,爲什麼我會欣賞啓發。

所以,我只好用蠻力,並提供我自己的序列化(也注意方法的反應類型更改爲String):

@GET 
@Path("/series/{uuid}/contents") 
public String getSessionsForSeries(@Context HttpServletRequest request, @Context HttpServletResponse response, @BeanParam ApiParams params) { 
    final SeriesDetailView series = seriesService.findByUuid(params.getUuid()); 
    if (series == null) { 
     response.setStatus(SC_NOT_FOUND); 
     return null; 
    } 
    List<ContentView> contentViewList = contentMapper.map(series.getContent()); 
    List<ContentView> results = contentViewList.stream() 
      .map(e -> mapContent(e, e.getUuid())).collect(Collectors.toList()); 
    ObjectMapper objectMapper = new ObjectMapper(); 

    try { 
     return objectMapper.writeValueAsString(results); 
    } catch (IOException e) { 
     response.setStatus(SC_INTERNAL_SERVER_ERROR); 
     return null; 
    } 
} 

由於教程在這裏:http://www.davismol.net/2015/03/05/jackson-json-deserialize-a-list-of-objects-of-subclasses-of-an-abstract-class/