DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Translating OData Queries to MongoDB in Java With Jamolingo
  • Jakarta EE 12 M2: Entering the Data Age of Enterprise Java
  • Prototype for a Java Database Application With REST and Security
  • Build a REST API With Just 2 Classes in Java and Quarkus

Trending

  • 5 AI Security Incidents That Broke Things in Production (and What They Have in Common)
  • Feature Flag Debt: Performance Impact in Enterprise Applications
  • GenAI Implementation Isn't Magic — It’s a Lifecycle
  • Why Stable RAG Answers Can Still Hide Unstable Evidence
  1. DZone
  2. Coding
  3. Java
  4. JAX-RS List Generic Type Erasure

JAX-RS List Generic Type Erasure

When using JAX-RS resource methods, be sure you know how to maintain your Lists' generic types. This guide will tell you how to handle type erasure.

By 
Alex Theedom user avatar
Alex Theedom
·
Dec. 18, 17 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
19.4K Views

Join the DZone community and get the full member experience.

Join For Free

Want to maintain a List's generic type? The problem is that when you want to return a List from a JAX-RS resource method, the generic type is lost.

The following code results in type loss:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllBooks() {
    List<Book> books = BookRepository.getAllBooks(); // queries database for all books
    return Response.ok(books).build();
}


And the following exception:

MessageBodyWriter not found for media type=application/json, 
    type=class java.util.Arrays$ArrayList, 
    genericType=class java.util.Arrays$ArrayList


Luckily, JAX-RS is packaged with a solution in the form of the GenericEntity class, which is designed to maintain the generic type. To use this class, just wrap the Collection in the GenericEntity like shown in this code:

import javax.ws.rs.core.GenericEntity;
...
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllBooks() {
    List<Book> books = BookRepository.getAllBooks(); // queries database for all books
    GenericEntity<List<Book>> list = new GenericEntity<List<Book>>(books) {};
    return Response.ok(list).build();
}


I was banging my head against the wall trying to figure this out, but thanks to this post by Adam Bein I was saved. Hopefully, this post finds you and stops any headaches before they begin.

@XmlRootElement
public class Book {

    private String isbn;
    private String title;
    private String author;
    private Float price;

    public Book() {
    }

    public Book(String isbn, String title, String author, Float price){
        this.isbn = isbn;
        this.title = title;
        this.author = author;
        this.price = price;
    }

    // Getters and Setters removed for brevity

}


Important Update

The behavior described above is demonstrated on GlassFish 4.1 and produces the following exception in the server.log files:

[2017-08-30T20:29:56.489+0100] [glassfish 4.1] [SEVERE] [] 
[org.glassfish.jersey.message.internal.WriterInterceptorExecutor] 
[tid: _ThreadID=70 _ThreadName=http-listener-1(2)] [timeMillis: 1504121396489] [levelValue: 1000] 
[[MessageBodyWriter not found for media type=application/json, 
    type=class java.util.ArrayList, 
    genericType=class java.util.ArrayList.]]


However, the same behavior is not seen on IBM WebSphere Liberty Profile. In fact, no error is thrown and the List of books is successfully serialized to a JSON representation. Further investigation shows that Liberty Profile is far more forgiving of deviations from the specification. More detailed research is needed to fully document the difference between server implementations I have only looked at GlassFish and Liberty Profile. However, as GlassFish is the reference implementation for Java EE, my advice is to develop with reference to its expectations because all other servers implementations should at least conform to its requirements.

The source code for this article is in the readlearncode_articles GitHub repository.

Further Reading

I regularly blog about Java EE on my blog readlearncode.com where I have recently published a mini-series of articles on the JAX-RS API.

Among the articles, there are discussions on bean validation failure in REST endpoints, how to work with Consumers and Producers, and how to create JAX-RS Resource Entities.

Do you want to know all the ways the @Context (javax.ws.rs.core.context) annotation can be used within your JAX-RS application. If so take a look at this five-parts series:

  • What is javax.ws.rs.core.context? (Part 1)
  • What is javax.ws.rs.core.context? (Part 2)
  • What is javax.ws.rs.core.context? (Part 3)
  • What is javax.ws.rs.core.context? (Part 4)
  • What is javax.ws.rs.core.context? (Part 5)
Java (programming language) REST

Published at DZone with permission of Alex Theedom. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Translating OData Queries to MongoDB in Java With Jamolingo
  • Jakarta EE 12 M2: Entering the Data Age of Enterprise Java
  • Prototype for a Java Database Application With REST and Security
  • Build a REST API With Just 2 Classes in Java and Quarkus

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook