【问题标题】:Can't retrieve JSONObject from my rest api无法从我的 rest api 中检索 JSONObject
【发布时间】:2016-10-15 20:58:23
【问题描述】:

所以我最近从 Jersey 1.x 迁移到了 2.x,经过一长串的问题,终于让它工作了。但是,每当我尝试访问返回 JSONObject 的资源时,我都会遇到问题。首先,这是我的示例方法:

@GET
@Path("/foobar")
@Produces(MediaType.APPLICATION_JSON)
public JSONObject print2() throws JSONException {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("hi", 22);
    return jsonObject;
}

现在,如果我将 Jettison 1.3.8 用于我的 JSONObject,如果我尝试访问此资源,我会得到以下信息:

{"escapeForwardSlashAlways":true}

不确定那里发生了什么。然后我尝试了一些旧版本的 Jettison 和 org.json 但这些给了我这个问题:

No serializer found for class org.json.JSONObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )

当这种方法在 Jersey 1.x 上对我很有效时,我不确定为什么会遇到这些问题。

【问题讨论】:

  • 你是否使用jackson来处理json序列化,反之亦然?
  • 我也对此感到震惊,使用 jersey 1.x 我能够返回 jsonobect。但是在球衣 2.x 中,我遇到了 escapeForwardSlashAlways 错误。我无法在 pogo 中设置值以返回响应,因为响应将嵌套 jsonobject 和 jsonarray ?为什么这适用于球衣 1.x 而不是 2.x?

标签: java jersey-2.0 jsonobject


【解决方案1】:

假设您使用的是 Servlet 3.0 及更高版本,以下示例可能会帮助您设置环境以使用 JSON 数据:

  1. 依赖:如果你使用的是 Maven,你需要以下依赖:

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.23.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
       <version>2.23.2</version>
    </dependency>
    

如果您不使用 Maven,则需要将相应的 jar 添加到您的类路径中。

  1. 定义 POJO 以包含要序列化为 JSON 的数据,例如,

    public class User {
       private String username;
       private String email;
    
       // getters + setters
    }
    
  2. 相应地修改你的资源方法:

    @GET
    @Path("/foobar")
    @Produces(MediaType.APPLICATION_JSON)
    public User print2() {
        User jsonObject = new User();
        jsonObject.setUsername("Me");
        jsonObject.setEmail("my@email.com");
        return jsonObject;
    }
    

打包部署,输出应该是:

{ “用户名”:“我”, “电子邮件”:“my@email.com” }

注意:此示例已在 Tomcat 8.5.5 上部署并运行。

【讨论】:

  • 我遇到了同样的问题 - {"escapeForwardSlashAlways":true}。我只是通过执行 Jsonobject.toString() 在字符串中获得了 JSON 对象
【解决方案2】:

我在同样的问题上苦苦挣扎,最终Jersey's bookmark exmple 提供了帮助。

问题是您的 Jersey 没有 JSONObject 的序列化程序,它尝试使用 BeanSerializer 代替。 Jettison JSONObject 只有一个公共 getter (isEscapeForwardSlashAlways),org.json.JSONObject 根本没有 getter,因此无法应用 BeanSerializer。

解决办法是针对(jettison json object):

  1. 添加依赖 jersey-media-json-jettison:
<dependency>
     <groupId>org.glassfish.jersey.media</groupId>
     <artifactId>jersey-media-json-jettison</artifactId>
     <version>2.26</version>
</dependency>
  1. 在您的 web.xml 中以声明方式注册放弃功能
<init-param>
     <param-name>jersey.config.server.provider.classnames</param-name>
     <param-value>org.glassfish.jersey.jettison.JettisonFeature</param-value>
<init-param>
  1. 或以编程方式在您的应用程序中:
@ApplicationPath("/")
public class MyApplication extends ResourceConfig {
     public MyApplication() {
          registerClasses(UsersResource.class);
          register(new JettisonFeature());
     }
}

web.xml:

<init-param>
     <param-name>javax.ws.rs.Application</param-name>
     <param-value>org.glassfish.jersey.examples.bookmark.MyApplication</param-value>
</init-param>

也许 org.json.JSONObject 也有针对 Jersey 的序列化器功能,我不知道...

【讨论】:

    【解决方案3】:

    另一个选项是允许响应将您的对象转换为 JSON。这也带来了添加 HTTP 代码的额外好处。因此,您可以返回 400、404、500 等,但仍会发回可由您的 JS 执行的 JSON 响应。您应该可以将您的 JSONObject 放在那里,因为它基本上只是扩展 Map - 或任何对象。

    @GET
    @Path("/foobar")
    @Produces(MediaType.APPLICATION_JSON)
    public Response print2() {
        User jsonObject = new User();
        jsonObject.setUsername("Me");
        jsonObject.setEmail("my@email.com");
        return Response.status(Response.Status.OK).entity(jsonObject).build());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-30
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2021-02-07
      相关资源
      最近更新 更多