3

I'm trying to create my own RESTful WS application using Jersey 2.12 based from this article. I want to return an XML representation of a class depending on the id been passed from the url, however, I'm getting a 500 response code when trying from either Advanced Rest Client Application (google chrome app) or browser. Below are the details:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-
    app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>WS_RESTful_Practice</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <!-- Register resources and providers under com.vogella.jersey.first package. -->
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>test.services</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
</web-app> 


TestRestModel.java

package test.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class TestRestModel{

    /**
     * 
     */
    private static final long serialVersionUID = -8391589100962515747L;
    private String name;
    private String content;

    public TestRestModel(String name, String content){
        this.name = name;
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}


TestResource.java

package test.services;

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

import test.dao.TestModelDao;
import test.model.TestRestModel;

@Path("/test")
public class TestResource {

    @GET
    @Path("{id}")
    public Response getModel(@PathParam("id") String id){
        return Response.ok().entity(TestModelDao.instance.getModel().get(id)).build();
    }
}


TestModelDao.java

package test.dao;

import java.util.HashMap;
import java.util.Map;
import test.model.TestRestModel;

public enum TestModelDao {
    instance;

    private Map<String, TestRestModel> container = new HashMap<String, TestRestModel>();

    private TestModelDao(){

        TestRestModel model = new TestRestModel("a", "this is first");
        container.put("1", model);
        model = new TestRestModel("b", "this is second");
        container.put("2", model);
        model = new TestRestModel("c", "this is third");
        container.put("3", model);
    }

    public Map<String, TestRestModel> getModel(){
        return container;
    }
}

I'm totally new to Jersey and REST. And I don't know how to log error from Jersey yet.

anonymouse
  • 109
  • 2
  • 9
  • Pls provide the stack trace of your 500 ... – zyexal Oct 06 '14 at 20:40
  • @zyexal thanks for the feedback. i don't know where to get the stacktrace and the web server doesn't print it neither. – anonymouse Oct 07 '14 at 08:41
  • If you start your server from your IDE (for example Eclipse) in debug mode, you should see something in you console view. Also you should be able to go through the code step by step then. So, try to enable debugging and report back afterwards ... – zyexal Oct 07 '14 at 18:16
  • @zyexal thanks. but that's the problem, the stacktrace doesnt print in the console. it just shows the server is started. – anonymouse Oct 08 '14 at 03:28

4 Answers4

15

This happens when you don't provide a default no arg constructor to your JAXB bean. So in your case you should amend the class by adding one:

  public TestRestModel(){

    }

This is due to a requirement in the JSR-222:

existing types, authored by users, are required to provide a no arg constructor. The no arg constructor is used by an unmarshaller during unmarshalling to create an instance of the type.

ACV
  • 9,964
  • 5
  • 76
  • 81
10

Stuff below is not the answer, but will probably help Johne to find out, whats up.

Out of the comments I've extract, that the main problem is, that you don't have any noticeable debug output in your console. So you are not able to find the issue by yourself, rather than give us some logs which would help to find out, what the exact problem could be.

Therefore pls implement an ExceptionMapper first, which will force console output of the stacktrace:

Example:

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class HelpMeExceptionMapper implements ExceptionMapper<Exception> {

    @Override
    public Response toResponse(Exception e) {
        e.printStackTrace();
        return Response
                    .status(Status.INTERNAL_SERVER_ERROR)
                    .type(MediaType.APPLICATION_JSON)
                    .entity(e.getCause())
                    .build();
    }

}

The ExceptionMapper has to be in a subpackage of your resource-config/providers path test.services:

<init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>test.services</param-value>
</init-param>

As i didn't implement your/vogellas code i would like to recommend you, to debug this step by step to find out whats up.

I reckon, that you miss to import something. But who knows ...

Have a nice day ...

zyexal
  • 1,570
  • 16
  • 23
  • @zyekal. wow. thanks man! the error is **Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions test.model.TestRestModel does not have a no-arg default constructor.** I just put a no arg constructor in the TestRestModel class and it works now. However, I dont know why it needs a no arg constructor and that's for me to find out. Thanks man :) – anonymouse Oct 09 '14 at 05:36
  • @zyexal tank you man, at least I'm able to track down my issue now! – Matthias Jul 14 '17 at 16:20
0

To the ones with the same problem, I had something like it but in my case it was a List that i wanted in my response. The source of the problem was that the object had a lazy load relationship and when I used GenericEntity> to return my list the same problem as occurred to me. Just change to null the relationship or bring the lazy load relation to the object before create GenericEntity> and it will be fine.

0

We need to understand this problem first Jersey returns 500 when trying to return an XML response. This issue is coming because of missing dependency in pom.xml and that is:

<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.2.11</version>
</dependency>  

But this is not enough. This will resolve the 500 Error but one more error will come, while using endpoint.

javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: com/sun/xml/bind/v2/model/annotation/AnnotationReader

To resolve this you need to add following dependencies too into pom.xml

<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.0.1</version>
</dependency>

        <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.1</version>
</dependency>

So this is the complete solution, to make your Jersey webApp work

Dupinder Singh
  • 7,175
  • 6
  • 37
  • 61
  • 1
    Thank you you this explanation, you helped me to resolve on problem in one time –  Apr 20 '20 at 07:29