尝试返回XML响应时,Jersey返回500

时间:2014-09-24 10:07:44

标签: jersey-2.0

我正在尝试使用基于this文章的Jersey 2.12创建自己的RESTful WS应用程序。我想根据从url传递的id返回类的XML表示,但是,当从 Advanced Rest Client Application (google chrome app)尝试时,我得到500响应代码或浏览器。以下是详细信息:

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;
    }
}

我对Jersey和REST完全不熟悉。我还不知道如何从泽西岛记录错误。

4 个答案:

答案 0 :(得分:15)

如果没有为JAXB bean提供默认的无arg构造函数,则会发生这种情况。因此,在您的情况下,您应该通过添加一个来修改该类:

  public TestRestModel(){

    }

这是由于JSR-222

中的要求
  

用户创作的现有类型需要提供无参数   构造函数。 unmarshaller使用no arg构造函数   解组以创建该类型的实例。

答案 1 :(得分:6)

下面的东西不是答案,但可能会帮助Johne找出答案,最新消息。

在我提取的评论中,主要问题是,您在控制台中没有任何明显的调试输出。所以你不能自己找到问题,而不是给我们一些有助于找出确切问题的日志。

因此请首先实现ExceptionMapper,这将强制执行stacktrace的控制台输出:

示例:

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();
    }

}

ExceptionMapper必须位于资源配置/提供者路径test.services的子包中:

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

由于我没有实现你的/ vogellas代码,我想建议你,一步一步调试,找出最新情况。

我估计,你错过了导入的东西。但谁知道......

祝你有愉快的一天......

答案 2 :(得分:0)

对于那些有同样问题的人,我有类似的东西,但在我的情况下,这是我在回复中想要的列表。问题的根源是该对象具有延迟加载关系,当我使用GenericEntity&gt;返回我的列表与我发生的问题相同。 在创建GenericEntity&gt;之前,只需更改为null关系或将延迟加载关系带到对象。没关系。

答案 3 :(得分:0)

我们需要先了解这个问题 Jersey returns 500 when trying to return an XML response。由于pom.xml中缺少相关性,因此将出现此问题,即:

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

但这还不够。这样可以解决500 Error,但是在使用端点时还会出现另一个错误。

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

要解决此问题,您还需要在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>

因此,这是使Jersey webApp正常工作的完整解决方案