【问题标题】:Dropwizard/Jersey returns Java List as JSON without root nodeDropwizard/Jersey 将 Java 列表返回为没有根节点的 JSON
【发布时间】:2013-01-23 20:26:21
【问题描述】:

我正在使用 dropwizard,它使用 jersey 和 jackson 作为 json。我的问题是当我返回一个列表时它没有指定根。

我有一个 POJO 类:

public class Company { 
public String id; 
public String name; 
public String address; 
}

我的资源是这样设置的:

@GET
@Path("/companies/all")
public List<Company> getAllCompanies(){
    ...
    return companies;
}

我得到以下回复:

[{
"id": "01",
"name": "Yammer Corp",
"address": "1 Finite Loop"
},
{
"id": "02",
"name": "DropWizards Inc",
"address": "4 Magic Square, Olympus"
}]

虽然我想要的是如下所示:

{"Companies" : 
[{
"id": "01",
"name": "Yammer Corp",
"address": "1 Finite Loop"
},
{
"id": "02",
"name": "DropWizards Inc",
"address": "4 Magic Square, Olympus"
}
]}

有什么想法吗?提前致谢。

【问题讨论】:

  • 你需要再包装一个 POJO。

标签: java jersey dropwizard


【解决方案1】:

您需要再创建一个包装List&lt;Company&gt; 的POJO

public class ApiResponse
{
   private List<Company> Companies;
   //Getter and Setter
   //Public Constructor
}

您的 GET 方法所需的更改是:

@GET
@Path("/companies/all")
public ApiResponse getAllCompanies(){
    //Set your ApiResponse Object with the companies List.
    ApiResponse apiResponse = new ApiResponse(companies);
    return apiResponse;
}

【讨论】:

  • 谢谢@Srinivas,我跟着你的实现,它成功了!我稍微修改了一下:public class JSONListWrapper { public List&lt;?&gt; itemlist; public JSONListWrapper(List&lt;?&gt; itemlist) { this.itemlist = itemlist; } }
  • 我倾向于使用名为 ApiResponse 的 POJO,它有 status_codestatus_messagedata,它是一个 Object 并充当有效负载。感觉比修改 ObjectMapper 简洁多了。
【解决方案2】:

我相信您可以使用 Jackson API 进行自定义。这是一种允许您使用 ObjectWriter 设置生成 JSON 的根的方法。

    @GET
    @Path("/companies/all")
    public Response getAllCompanies() throws JsonProcessingException {
        List<Company> companies = Lists.newArrayList();
        Company yc = new Company();
        yc.id = "01";
        yc.name = "Yammer Corp";
        yc.address = "1 Finite Loop";
        companies.add(yc);
        Company dw = new Company();
        dw.id = "02";
        dw.name = "DrowWizards Inc";
        dw.address = "4 Magic Square, Olympus";
        companies.add(dw);

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectWriter writer = objectMapper.writer();
        String entity = writer.withRootName("Companies").writeValueAsString(companies);
        return Response.ok(entity).build();
    }

【讨论】:

    【解决方案3】:

    如果您查看您要求返回公司列表的代码:

    public List<Company> getAllCompanies(){
    

    如果你想返回一个带有 Companies 值的 JSON 对象,那么你需要一个与之匹配的合适的 Java 对象。

    public class MyListOfCompanies {
      List<Companies> companies;
    }
    

    然后你会要求你的代码返回它:

    public MyListOfCompanies getAllCompanies(){
    

    但是,如果您真的想这样做,请考虑一下。如果您考虑某人为您的 API 进行编码的情况,他们是否更愿意收到公司列表(正如他们所要求的并且 API 暗示他们将获得),或者除了包含公司列表之外没有其他用途的对象?

    最后,对于良好的 REST 设计,获取所有公司列表的常用方法是使用路径 /companies,而不是 /companies/all。

    【讨论】:

    • 我同意 REST Url /companies 而不是 /companies/all。但是,我看到了“命名”JSON 中每个参数的有效用例。我遇到过在 Body 中发送此类内容的人,但没有一个人被命名。当 JSON 具有多级时,这是相当困难的。
    • 请记住,一旦您有多个级别,那么除了顶级之外的所有内容都将被命名。您可以在问题的输出中看到这一点。此外,根据定义,您的顶层将永远被命名。您在创建容器对象时所做的只是将一个新的未命名对象放在顶层。
    猜你喜欢
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多