阅读 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.