Jersey returns 500 when trying to return an XML response

北城以北 提交于 2019-12-04 04:55:16

问题


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.


回答1:


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.




回答2:


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 ...




回答3:


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.



来源:https://stackoverflow.com/questions/26014184/jersey-returns-500-when-trying-to-return-an-xml-response

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!