1

I'm trying to learn the implementation of RESTful Web services using JAX-RS.

I have a class called MovieObject that contains basic info about movies & a class called ResourceHandler that takes care of the request and sends the response.

Following is my MovieObject.java

package org.auro.self.movielib.resource;

public class MovieObject {

    private String movieName;
    private String yearOfRelease;
    private int movieRating;

    public MovieObject(){

    }

    public MovieObject(String movieName, 
            String yearOfRelease, 
            int movieRating){

        this.movieName = movieName;
        this.yearOfRelease = yearOfRelease;
        this.movieRating = movieRating;
    }

    public String getMovieName(){
        return movieName;
    }


    public String getYearOfRelease(){
        return yearOfRelease;
    }

    public int getMovieRating(){
        return movieRating;
    }
}

Following is my ResourceHandler.java

package org.auro.self.movielib.resource;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/message")
public class ResourceHandler {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public List<MovieObject> getListOfMovies(){
        MovieObject mv1 = new MovieObject("The Independence Day 1", "1996", 7);
        MovieObject mv2 = new MovieObject("The Independence Day 2", "2016", 4);

        List<MovieObject> listOfMovies = new ArrayList<MovieObject>();

        listOfMovies.add(mv1);
        listOfMovies.add(mv2);

        return listOfMovies;
    }

}

Following is my index.jsp

<html>
<body>
    <h2>Jersey RESTful Web Application!</h2>
    <p><a href="webapi/myresource">Jersey resource</a>
    <p>Visit <a href="http://jersey.java.net">Project Jersey website</a>
    for more information on Jersey!

    <p> Get Movies <a href="webapi/message"> here</a>
</body>
</html>

And finally, the web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>org.auro.self.movielib</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
</web-app>

If you look at my index.jsp, you will notice that any request to <p> Get Movies <a href="webapi/message"> here</a> is actually taken care of by ResourceHandler.java

A GET request to that class should return a list of movies as plain text, but I end up getting an HTTP Status 500 - Internal Server Error

And this is what I get in my console

INFO: Server startup in 2430 ms
Aug 20, 2016 11:52:58 PM org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
SEVERE: MessageBodyWriter not found for media type=application/xml, type=class java.util.ArrayList, genericType=java.util.List<org.auro.self.movielib.resource.MovieObject>.

Is there anything I'm missing that's causing this error?

Maciej Marczuk
  • 3,593
  • 29
  • 28
Auro
  • 1,578
  • 3
  • 31
  • 62
  • Have you googled for that exception? or searched here? http://stackoverflow.com/questions/26207252/messagebodywriter-not-found-for-media-type-application-json – Koos Gadellaa Aug 20 '16 at 20:09
  • Make sure you have all the necessary dependencies or consider using Maven. look here : http://stackoverflow.com/questions/29136404/severe-messagebodywriter-not-found-for-media-type-application-json-type-class – chenchuk Aug 20 '16 at 20:10
  • You can't render an `ArrayList` as XML (application/xml), though I don't know why it's trying to render to XML when your method says `@Produces(MediaType.TEXT_PLAIN)` (text/plain). But if it had actually rendered to plain text, why would you even want to get the `toString()` representation of an `ArrayList`? That makes no sense. So answer me this: What did you actually intend/expect to get back when clicking the `webapi/message` link? – Andreas Aug 20 '16 at 20:17
  • Meta: looks like your JAX-RS implementation is Jersey? If so, you might tag it with that. Plus your specific JEE server if you're using one. Those will probably be more relevant to solving the problem than tags like jsp or http-status-codes. – dbreaux Aug 24 '16 at 04:21

1 Answers1

0

This is content negotiation problem (misscommunication).

You should either change your application to return xml instead of TEXT_PLAIN:

 @Produces({ MediaType.APPLICATION_XML })

or invoke your service with request containing Accept: text/plain header (by default it's Accept:text/html,application/xml or something like that)

You could also try url-based content negotiation, but this is AFAIK only Resteasy feature:

https://docs.jboss.org/resteasy/docs/3.0.6.Final/userguide/html/JAX-RS_Content_Negotiation.html

Maciej Marczuk
  • 3,593
  • 29
  • 28
  • This seems a reasonable possibility. And you could certainly *try* `APPLICATION_XML` to see if that works. I also wouldn't be surprised if a JAX-RS implementation doesn't want to render complex objects as plain text. I certainly wouldn't want to rely on any consistent rendering that way. – dbreaux Aug 24 '16 at 04:24