簡體   English   中英

Java REST 反序列化列表

[英]Java REST deserialize list

我正在使用 JAX-RS 構建 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 有更多的屬性,它們都擴展了 ContentView。 我已經正確連接了所有映射器,因此每個相應類的所有實例都正確設置了其所有屬性。 我不使用任何額外的映射器 - 對象屬性根據相應 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;
    }
}

現在,問題來了:

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

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

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

但是我終生找不到為什么這些在 List 中沒有得到正確反序列化的原因。 我錯過了什么?

答案如下:

出於某種原因,List 的序列化器被搞砸了,並且在序列化默認為聲明的內容類 (ContentView) 時。

如果有人知道為什么我會欣賞啟蒙。

因此,我不得不使用蠻力並提供我自己的序列化(請注意該方法的響應類型已更改為 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/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM