球衣消耗二维数组

jersey consume two dimensional array

我正在使用 jersey 开发 REST 网络服务。

我正在按以下格式提交数据:

var data = new Array();
data.push({ name: 'field1', value: "123" });
data.push({ name: "field2", value: "XYZ" });

现在我想发送以下格式的附加数据:

    var products = new Array();
    products.push({ name: 'product1', value: "5" });
    products.push({ name: 'product2', value: "8" });
    products.push({ name: 'product3', value: "12" });

    data.push({ name: "products", value: products });

泽西网络服务代码:

@Path("/myRequestPath")
@POST
@Produces({ MediaType.APPLICATION_JSON })
public MetaDataStatus processChangeRequest(
    @FormParam("field1") String field1,
    @FormParam("field2") String field2,
          //how to read products here?
    )
{
}

我的问题是如何在 jersey 网络服务中使用以上 products 数据?

不要以这种格式发送数据。使用可轻松映射到 Java 对象的对象。您需要了解的第一件事是您的数据在 JSON 中的外观以及映射到 Java 对象的方式。

首先你有一个数组var data = new Array();。所以最初你在 JSON

中有以下内容
[]

这只是一个空数组。在 Java JSON/POJO 映射世界中,这通常映射到 Java List 或普通 java 数组,因此您现在只需要

List data = new ArrayList();

然后开始添加 Java 脚本对象 ({ }),它映射到 JSON 个对象 ({ })。

所以在前两次添加之后,你有

[
  { name: 'field1', value: "123" },
  { name: 'field2', value: "XYZ" }
]

但是 JSON 个对象 ({..}) 映射到 Java 个对象。所以我们需要一个 class 来保存 namevalue 字段。例如

public class KeyValuePair {
    public String name;
    public String value;
}

所以现在你有一些映射到

List<KeyValuePair> data = new ArrayList<>();
data.add(new KeyValuePair("field1", "123"));
data.add(new KeyValuePair("field2", "XYX"));

如您所见,它开始变得非常难看。这是因为您发送数据的方式。但是正如您从 KeyValuePair 示例中看到的那样,Java 脚本属性,即 namevalue 映射到 Java 字段 namevalue。所以你应该做的是忘记名称值对,简单地将 Javacript 对象直接映射到 Java 对象。例如

var obj = {
    field1: "123",
    field2: "XYZ",
    products: [
        { name: "product1", price: 10 },
        { name: "product2", price: 20 },
        { name: "product2", price: 30 }
    ]
};
var data = JSON.stringify(obj);
$.ajax({
    url:url,
    data: data,
    contentType: "application/json",
    ...
});

所以现在 Java脚本 obj 会映射到 Java 就像

public class MyObject {
    public String field1;
    public String field2;
    public List<Product> products;
    // should actually be private with getters and setters
}

public class Product {
    public String name;
    public double price;
}

我希望您能看到 Java 脚本如何直接映射到 Java class。所以现在你可以简单地将它作为方法

@Path("/myRequestPath")
@POST
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public MetaDataStatus processChangeRequest(MyObject obj) {}

不过,要使其正常工作,您需要确保您拥有泽西岛的 JSON 提供商。如果你没有,你会得到一个异常,如 "MessageBodyReader not found for media type application/json and Java type MyObject"。如果您看到此异常,您可以使用异常消息进行 google 搜索。有很多答案表明您需要添加的内容。我自己可以告诉你,但你没有提供足够的信息让我可以准确地告诉你你需要什么。

如果您在解决问题时需要帮助,请告诉我您使用的 Jersey 版本以及您是否使用 Maven。

更新

对于 Maven,只需为 JSON/POJO 支持添加此依赖项

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.7</version>
</dependency>

然后在你的web.xml

中配置
<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>