阅读 JSON 以使用 JAX-RS 进行映射
Reading JSON to map with JAX-RS
我正在编写一个 Java EE REST 应用程序(它在 Glassfish 4.1 下运行)并且我在读取一个简单的键值 JSON 列表时遇到问题。我正在尝试使用 POJO class 生产和消费 JSON,生产工作正常,但消费不起作用。
让我们来看看代码。我用于生产和消费的 POJO class JSON 是这样的:
public class Transport {
protected Integer id;
protected String name;
protected Map<String, String> fields;
// ...getters and setters...
}
REST 资源导入那些库(我把相关的放在这里):
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
生成 JSON 的方法工作正常,这里是:
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("test")
public Response testGet() {
Transport sct = new Transport();
sct.setId(1);
sct.setName("test");
HashMap<String, String> t1 = new HashMap();
t1.put("aaa", "bbb");
t1.put("bbb", "ccc");
t1.put("ccc", "ddd");
sct.setFields(t1);
// createOkResponse is a class method that return Response type
return createOkResponse(sct);
}
所以我正确地获得了这个输出:
{
"id": 1,
"name": "test",
"fields": {
"aaa": "bbb",
"ccc": "ddd",
"bbb": "ccc"
}
}
消费方法JSON,使用相同的POJO:
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("test")
public Response testPut(Transport sct) {
Map<String, String> fields = sct.getFields();
// this code throws a NullPointerException at fields.entrySet()
// because fields is always null
//for (Entry<String, String> field : fields.entrySet()) {
// LOG.log(Level.INFO, "*** field: {0} = {1}", new Object[]{field.getKey(), field.getValue()});
//}
return createOkResponse(sct);
}
使用与上面相同JSON的服务将导致设置了 id 和 name 属性的 sct 对象,但字段 属性 为 null,因此该方法的响应是:
{
"id": 1,
"name": "test",
"fields": null
}
好像 {"aaa": "bbb", "ccc": "ddd", "bbb": "ccc"}
JSON 对象被忽略了。我试过谷歌搜索,但我不明白我的代码有什么问题,而且我在 glassfish 日志中没有看到任何错误或警告。
任何的想法?谢谢。
您可以使用 XmlAdapter
,如 中所述。问题在于 MOXy 处理地图的方式。它在引擎盖下使用 JAXB,这意味着用于 XML,并且 XML 不能很好地映射到地图(或 key/value)对。
出于这个原因,我建议使用 Jackson,而不是将 MOXy 用于 JSON(这是 Glassfish 中的默认 JSON 提供程序)。 Jackson 也应该包含在 Glassfish 4.1 中。但是您需要禁用 MOXy,这样 Jackson 才能自行注册。要禁用 MOXy,只需将 Jersey 属性 jersey.config.server.disableMoxyJson
设置为 true
.
我正在编写一个 Java EE REST 应用程序(它在 Glassfish 4.1 下运行)并且我在读取一个简单的键值 JSON 列表时遇到问题。我正在尝试使用 POJO class 生产和消费 JSON,生产工作正常,但消费不起作用。 让我们来看看代码。我用于生产和消费的 POJO class JSON 是这样的:
public class Transport {
protected Integer id;
protected String name;
protected Map<String, String> fields;
// ...getters and setters...
}
REST 资源导入那些库(我把相关的放在这里):
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
生成 JSON 的方法工作正常,这里是:
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("test")
public Response testGet() {
Transport sct = new Transport();
sct.setId(1);
sct.setName("test");
HashMap<String, String> t1 = new HashMap();
t1.put("aaa", "bbb");
t1.put("bbb", "ccc");
t1.put("ccc", "ddd");
sct.setFields(t1);
// createOkResponse is a class method that return Response type
return createOkResponse(sct);
}
所以我正确地获得了这个输出:
{
"id": 1,
"name": "test",
"fields": {
"aaa": "bbb",
"ccc": "ddd",
"bbb": "ccc"
}
}
消费方法JSON,使用相同的POJO:
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("test")
public Response testPut(Transport sct) {
Map<String, String> fields = sct.getFields();
// this code throws a NullPointerException at fields.entrySet()
// because fields is always null
//for (Entry<String, String> field : fields.entrySet()) {
// LOG.log(Level.INFO, "*** field: {0} = {1}", new Object[]{field.getKey(), field.getValue()});
//}
return createOkResponse(sct);
}
使用与上面相同JSON的服务将导致设置了 id 和 name 属性的 sct 对象,但字段 属性 为 null,因此该方法的响应是:
{
"id": 1,
"name": "test",
"fields": null
}
好像 {"aaa": "bbb", "ccc": "ddd", "bbb": "ccc"}
JSON 对象被忽略了。我试过谷歌搜索,但我不明白我的代码有什么问题,而且我在 glassfish 日志中没有看到任何错误或警告。
任何的想法?谢谢。
您可以使用 XmlAdapter
,如
出于这个原因,我建议使用 Jackson,而不是将 MOXy 用于 JSON(这是 Glassfish 中的默认 JSON 提供程序)。 Jackson 也应该包含在 Glassfish 4.1 中。但是您需要禁用 MOXy,这样 Jackson 才能自行注册。要禁用 MOXy,只需将 Jersey 属性 jersey.config.server.disableMoxyJson
设置为 true
.