【问题标题】:Reading JSON to map with JAX-RS读取 JSON 以使用 JAX-RS 进行映射
【发布时间】:2016-06-08 03:08:24
【问题描述】:

我正在编写一个 Java EE REST 应用程序(它在 Glassfish 4.1 下运行),但我在读取一个简单的键值 JSON 列表时遇到了问题。我正在尝试使用 POJO 类生成和消费 JSON,生产工作正常,但消费不起作用。 让我们来看看代码。我用于生产和消费 JSON 的 POJO 类是这样的:

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消费服务会得到一个sct对象,设置了id和name属性,但是fields属性为null,所以方法的响应是:

{
  "id": 1,
  "name": "test",
  "fields": null
}

就像{"aaa": "bbb", "ccc": "ddd", "bbb": "ccc"} JSON 对象被忽略了。我试过用谷歌搜索,但我不明白我的代码有什么问题,而且我在 glassfish 日志中没有看到任何错误或警告。 任何的想法?谢谢。

【问题讨论】:

  • 不是 100% 确定,但问题可能在于 MOXy(默认 JSON 提供程序)如何处理地图。您可以尝试禁用 MOXy,以便 Jersey 使用 Jackson,然后看看会发生什么。尝试将属性jersey.config.server.disableMoxyJson配置为true
  • 嗨@peeskillet,为Jackson 更换MOXy 就行了,谢谢!无论如何,有没有办法用 MOXy 读取这个 JSON?我觉得很奇怪它可以生成一个无法读取的 JSON。
  • 你可以试试this maybe
  • @peeskillet 你想把你的第一条评论作为一个回答,也许添加第二条评论的链接,这样我可以接受吗?谢谢

标签: java json rest glassfish jax-rs


【解决方案1】:

您可以使用XmlAdapter,如this post 中所述。问题在于 MOXy 处理地图的方式。它在底层使用了 JAXB,这本来是用于 XML 的,而 XML 不能很好地映射到 Maps(或键/值)对。

因此,我建议使用 Jackson,而不是使用 MOXy for JSON(这是 Glassfish 中的默认 JSON 提供程序)。 Jackson 也应该包含在 Glassfish 4.1 中。但是您需要禁用 MOXy,以便 Jackson 可以自行注册。要禁用 MOXy,只需将 Jersey 属性 jersey.config.server.disableMoxyJson 设置为 true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    相关资源
    最近更新 更多