Solution: NetBeans-Generated REST Client Code Does Not Handle Lists

DZone 's Guide to

Solution: NetBeans-Generated REST Client Code Does Not Handle Lists

Love NetBeans but having trouble with its generated REST client code when dealing with Lists? Let's dive into the reasons behind it as well as the solution.

· Java Zone ·
Free Resource

In my Introduction to Java Web Services course, I use as an example a web service that returns a List of JPA entity objects of type Fish. A Fish is just several fields that describe different aspects of aquarium fish. For many years, going back to 2004, I only showed SOAP services. The code generator in my favorite IDE, NetBeans, output working server and client code. Then, about five years ago, I added REST services to my curriculum.

The NetBeans code generator for REST services produced workable code, except in one situation for REST clients. The List type could not be returned by the generated code. Here is what the client generated code looks like:

public <T> T getJson(Class<T> responseType) throws ClientErrorException {
    WebTarget resource = webTarget;
    return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);

REST client method

To call this code I used:

List<Fish> fishies = client.getJson(List.class);

Calling the REST service

When I ran this code, I received the following error message:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=interface java.util.List.

Error message

This error has been around from the first time I explored REST services. After spending a few hours looking for a solution five years ago, I came across one that showed (by adding a dependency to my pom.xml) the code will work.


Maven dependency

Genson, a Java and Scala JSON conversion library, was created to deal with several issues in REST services, one of which was to simplify working with Lists. You can learn more about this library at https://owlike.github.io/genson/. I added the dependency to the client POM file and never gave it another thought until today. How could jax-rs not be able to handle a List? So, I did more research.

I discovered that this was a problem that many had encountered — and not just NetBeans users. There were several suggested solutions, but the one that made the most sense showed me that the problem was not with jax-rs but with the code that NetBeans generated.

The solution came from Adam Bien’s blog. Adam is one of the foremost Java EE developers and trainers and is in great demand as a speaker. I have had the good fortune of meeting him at JavaOne. His blog showed that responses from a REST service that are in a List must be wrapped in a GenericTypeclass. First, I changed the generated getJson method, renaming it getJson2:

public List<Fish> getJson2() throws ClientErrorException {
    WebTarget resource = webTarget;
    return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON)
        .get(new GenericType<List<Fish>>() { });

Corrected method for returning a List

If you compare this to the generated code shown earlier in this article, you will see that this method is now tightly coupled to the data type it is returning. The generated code was designed to work in all cases because it used generics. As generated, you needed to pass the class of the returned data. The problem is that you cannot pass a generic type such as List<Fish>.class instead of List.class.

When the return type is a generic collection, Adam pointed out that it must be wrapped in a GenericType class that is part of jax-rs. The code that NetBeans produces should work in all cases but not in this case.

The dependency for Genson is now removed and my executable client is 378K smaller.

Thanks to Adam Bien for his article. Read his blog at http://www.adam-bien.com and follow him on Twitter at @AdamBien

java ,netbeans ,rest client ,generated code ,lists ,tutorial

Published at DZone with permission of Ken Fogel , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}