0

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!

Ravi
  • 30,829
  • 42
  • 119
  • 173
Igor
  • 1,397
  • 3
  • 24
  • 56

2 Answers2

1

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.

Ravi
  • 30,829
  • 42
  • 119
  • 173
  • I don't think that's the case. Even if I return a single user I get the same error. I tried the approach you mentioned but still not working. I'm trying this approach: https://jersey.github.io/documentation/latest/media.html#json and saw this example: https://github.com/jersey/jersey/tree/2.26/examples/json-moxy but then I get this error: Caused by: java.lang.ClassNotFoundException: org.glassfish.jersey.moxy.json.MoxyJsonConfig at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1275) – Igor Jan 03 '18 at 12:03
  • @Igor Are you using moxy ?? or jackson ?? You don't need any of these jersey will take care of serialization and deserialization. – Ravi Jan 03 '18 at 13:47
  • So, the "jersey-quickstart-webapp" is comming with this: jersey-media-json-binding, but it didn't work so I went to the documentation and decided to go with moxy. So basically what I saw is that all I need to do is to add the dependency and nothing more... But then I get this message: SEVERE: MessageBodyWriter not found for media type=application/json. – Igor Jan 03 '18 at 15:53
  • @Igor I would suggest to use only jersey lib and remove all library. Jersey will take care of all – Ravi Jan 03 '18 at 16:30
  • So which libraries should I keep? If I remove the moxy I still get the same error. The thing is that it works with APPLICATION_XML, so everything seems to be working fine. – Igor Jan 03 '18 at 16:34
  • @Igor what else you have?? can you take screenshot of all libs and post. Also, if something is working, it doesn't mean it is always correct. – Ravi Jan 03 '18 at 16:35
  • I added the project on github so you can take a look. I left it with APPLICATION_XML, which is working. It's already with the moxy lib and using version 2.26 for jersey. I built it using jersey-quickstart-webapp, so you can deploy it do tomcat for instance. https://github.com/schkrab/agenda - I'm wondering if there is something on my environment because even running other versions I still get the same error like moxy is not on the classpath. – Igor Jan 03 '18 at 17:01
  • @Igor I'm telling you same thing, jersey takes cares of serializing and deserializing to specified media type. I'm not familiar with pom.xml, but, I would suggest you to compare with this site. https://howtodoinjava.com/jersey/jersey-2-hello-world-application-tutorial/. – Ravi Jan 03 '18 at 18:06
  • @Igor I'm repeating again, conversion of JSON and XML can be taken care by jersey itself, you don't need any additional library. I have done this in one of my project. Just keep jersey library nothing else and make changes as per suggestion (refer my post) – Ravi Jan 03 '18 at 18:08
  • @Igor make sure you upvote and accept the answer (if it was helpful). – Ravi Jan 05 '18 at 03:22
  • Thank for the support!! I wanted to use the moxy lib, so I tried with an earlier version of the archetype (2.25 instead of 2.26) then it worked fine. – Igor Jan 05 '18 at 22:59
1

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/

joedev
  • 65
  • 5