简体   繁体   中英

Can't retrieve JSONObject from my rest api

So I recently moved from Jersey 1.x to 2.x and after a long list of problems finaly got it working. But whenever I try to reach a resource which returns a JSONObject I get problems. First of, here is my example method:

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

Now if I use Jettison 1.3.8 for my JSONObject, I get the following if I try to reach this resource:

{"escapeForwardSlashAlways":true}

Not sure whats going on there. Then I tried some older versions of Jettison and also the org.json but these gives me this issue instead:

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

Not sure why I get these problems when this kind of method worked fine for me on Jersey 1.x.

I was struggling with the same issue, and eventually Jersey's bookmark exmple helped.

The problem is that your Jersey has no serializer for JSONObject and it tries to use BeanSerializer instead. Jettison JSONObject has only one public getter ( isEscapeForwardSlashAlways ) and org.json.JSONObject has no getters at all so BeanSerializer cannot be applied.

The solution is for (jettison json object):

  1. Add dependency jersey-media-json-jettison:
 <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jettison</artifactId> <version>2.26</version> </dependency> 
  1. Register the jettison feature declaratively in your 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. Or programmatically in your application:
 @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>

Perhaps org.json.JSONObject has such serializer feature for Jersey too, I don't know...

Assuming you are using Servlet 3.0 and above, the following example might help you to setup your environment to work with JSON data:

  1. Dependency: if you are using Maven you need the following dependencies:

     <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> 

If you are not using Maven, you need to add the correponding jars into your classpath.

  1. Define POJOs to contain the data you want to serialize to JSON, for example,

     public class User { private String username; private String email; // getters + setters } 
  2. Modify your resource method accordingly:

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

Package and deploy, and the output should be:

{ "username": "Me", "email": "my@email.com" }

Note: This example is deployed and works on Tomcat 8.5.5.

Another option is to allow the Response to convert your object to JSON. This gives the added benefit of adding the HTTP code as well. So you can return a 400, 404, 500 etc. and still send back a JSON response that can be acted upon by your JS. You should be able to drop your JSONObject in there since it's basically just extended Map - or any object for that matter.

@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());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM