简体   繁体   中英

Jersey 2.26 REST API - Json return not working

I have this simple example to return a list of User in JSON. It works fine with XML, but not working with JSON. Not sure what I'm doing wrong. Is there anything else I need to do? I created the project using jersey-quickstart (maven) and uncommented the dependency to support JSON.

<dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-binding</artifactId>
        </dependency>

On my User domain I have the @XmlRootElement annotation and there are just 2 fields. Id (long) and Username (String)

And that's what I have on my resource:

@GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getUsers(){
        return userService.getAllUsers();
    }

And that's what I have on my service:

public List<User> getAllUsers(){
        List<User> users = new ArrayList<User>();

        User u1 = new User(1l, "user_1");
        User u2 = new User(2l, "user_2");
        User u3 = new User(3l, "user_3");

        users.add(u1);
        users.add(u2);
        users.add(u3);

        return users;
    }

By changing the APPLICATION_JSON to APPLICATION_XML it works fine and return the xml with the list of users. With APPLICATION_JSON I get this:

SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<com.wordpress.whiteboardcoding.agenda.domain.User>.

Not sure if there is something else I had to do other then uncommenting the jersey-media-json-binding. Any thoughts?

Trying to find out if there is something different as it's not using the jersey-media-moxy anymore.

Thanks!

You cannot define the response JSON as List, as the JAXB is unable to identify the @XmlRootElement over the java.util.List or java.util.ArrayList class definition.

So, I would suggest to wrap your User list.

@XmlRootElement(name = "Users")
public class Users {

    List<User> userList;

    //setters and getters goes here
}

@XmlRootElement()
class User{
   //fields here
}

And, your service would be

@GET
@Produces(MediaType.APPLICATION_JSON)
public Users getUsers(){
    Users users = new Users ();
    users.setAllUsers (userService.getAllUsers());
    return users;
}

Also, make sure, you have added all libraries with same version.

The current answer does not address the jersey-media-json-binding artifact referenced in the Jersey quickstart project (and this seems to the basis of the original issue in the question posed).

The Jersey website makes no obvious mention of the jersey-media-json-binding dependency or its usage. All we have is a suggestion in the quickstart pom that Json support will be available should the dependency be resolved.

As far as I can tell, the jersey-media-json-binding is a mapping for JSON-B (the new Java API for JSON binding).

I coming at Jersey fresh so don't yet fully understand all the JSON mapping options available (eg moxy, jaxb, json-p, etc) and their association with the JSON-B binding but I think this may explain the difficulties encountered by Igor.

There is also scope for confusion around JSON-P in relation to JSON-B. Some further dependency details here .

UPDATE

I'm still badly confused by all of this but a little more information is available from Cassio Mazzochi Molin's answer here: Jersey 2 + Jackson Annotation / @JsonIgnore

ANOTHER UPDATE

My advice is not to use the jersey-media-json-binding.

It uses Yasson 1.0 (as of Jersey 2.7) to implement the json functionality. Although Yasson is the reference implementation for JSON-B, ver 1.0 has many problems and limitations. It is simply much easier to register your own provider based on GSON or some other mature library; see example here: https://howtodoinjava.com/jersey/jax-rs-gson-example/

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