线程“main”中的异常javax.ws.rs.NotAcceptableException:HTTP 406不可接受

时间:2015-04-03 19:05:10

标签: java rest jersey jackson jax-rs

执行REST客户端时出现以下异常:

InboundJaxrsResponse{ClientResponse{method=GET, uri=http://localhost:8080/com.dcr.jersey.first/webapi/todo, status=406, reason=Not Acceptable}}
Exception in thread "main" javax.ws.rs.NotAcceptableException: HTTP 406 Not Acceptable

在Web浏览器上(当tomcat运行时),URL:http://localhost:8080/com.dcr.jersey.first/webapi/todo提供输出

todo>
<description>This is my first todo - Description</description>
<summary>This is my first todo - Summary</summary>
</todo>

但运行客户端代码会抛出异常,这里缺少的映射是什么?,感谢您的指导(包括所有代码示例)

这是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>com.dcr.jersey</param-value> -->
<!--             <param-value>com.dcr.jersey.first</param-value> -->
                <param-value>com.dcr.jersey.jaxb.model</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>

这是执行的TodoResourceCliient:

package com.dcr.jersey.client;

import java.net.URI;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;

import org.glassfish.jersey.client.ClientConfig;

public class TodoResourceCliient {


    public static void main(String[] args) {
        ClientConfig config = new ClientConfig();
        Client client = ClientBuilder.newClient(config);
        WebTarget target = client.target(getBaseURI());

                System.out.println(target.path("webapi").path("todo").request()
                        .accept(MediaType.TEXT_PLAIN).get(Response.class)
                        .toString());

                System.out.println(target.path("webapi").path("todo").request()
                        .accept(MediaType.TEXT_HTML).get(String.class));

                System.out.println(target.path("webapi").path("todo").request()
                        .accept(MediaType.TEXT_XML).get(String.class));

                System.out.println(target.path("webapi").path("todo").request()
                        .accept(MediaType.TEXT_PLAIN).get(String.class));

                System.out.println(target.path("webapi").path("todo").request()
                        .accept(MediaType.APPLICATION_JSON).get(String.class));
    }

    private static URI getBaseURI() {

        return UriBuilder.fromUri("http://localhost:8080/com.dcr.jersey.first").build();

      }

}

TodoResource.java:

package com.dcr.jersey.jaxb.model;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/todo")
public class TodoResource {
    @GET
      @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
      public Todo getXML() {
        Todo todo = new Todo();
        todo.setSummary("This is my first todo - Summary\n");
        todo.setDescription("This is my first todo - Description\n");
        return todo;
      }
      // This can be used to test the integration with the browser
      @GET
      @Produces({ MediaType.TEXT_XML,MediaType.TEXT_PLAIN,MediaType.TEXT_HTML})
      public Todo getHTML() {
        Todo todo = new Todo();
        todo.setSummary("This is my first todo - Summary\n");
        todo.setDescription("This is my first todo - Description\n");
        return todo;
      }
}

Todo.java:

package com.dcr.jersey.jaxb.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

public class Todo {

    private String summary;
    private String description;

    public String getSummary() {
        return summary;
    }
    public void setSummary(String summary) {
        this.summary = summary;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }


}

来自Console的Stacktrace:

InboundJaxrsResponse{ClientResponse{method=GET, uri=http://localhost:8080/com.dcr.jersey.first/webapi/todo, status=500, reason=Internal Server Error}}
Exception in thread "main" javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
    at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1002)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:799)
    at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:91)
    at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:687)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:683)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:307)
    at com.dcr.jersey.client.TodoResourceCliient.main(TodoResourceCliient.java:27)

pom.xml中包含的依赖项:我是否缺少任何依赖项?

<dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
            <!-- artifactId>jersey-container-servlet</artifactId -->
        </dependency>
<!--          JSON support -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>

    </dependencies>

4 个答案:

答案 0 :(得分:4)

请参阅Http Status Codes

  

406不可接受

     

请求标识的资源只能生成响应实体,这些响应实体的内容特征根据请求中发送的接受标头不可接受。

.accept(mediatype)是为请求设置Accept标头的内容。您目前有五个请求,每个请求都接受不同的类型

  

MediaType.TEXT_PLAINMediaType.TEXT_HTML MediaType.TEXT_XML MediaType.TEXT_PLAIN MediaType.APPLICATION_JSON

这是Content-Negotiation正在进行中。服务器端的配置是使用@Produces(与Accept标头一起使用)和@Consumes(与Content-Type标头一起使用)。

话虽如此,请查看所有@Produces注释。您目前仅支持媒体类型的制作

  

MediaType.APPLICATION_XMLMediaType.TEXT_XMLMediaType.APPLICATION_JSON

上面缺少的是粗体。删除那些,如果一切正确,这应该适合你。

答案 1 :(得分:1)

检查您的内容类型!

设置为.accept(MediaType.TEXT_PLAIN)对我有用。

答案 2 :(得分:0)

正如peeskillet正确陈述的那样,您的客户端使用accept调用(MediaType.TEXT_PLAIN)并接受(MediaType.TEXT_HTML)会导致问题,因为您的TodoResource方法未在@Produces注释中指定这些媒体类型。

无论

  1. 更改您的TodoResource类以支持这些媒体类型
  2. 更改您的客户端代码以删除与这些媒体类型相对应的调用

答案 3 :(得分:0)

用简单的语言&#34; HTTP 406 Not Acceptable&#34;表示您对服务器的请求没有失败,而服务器告诉您,您要求的请求的内容类型无法从后端提供,或者您需要在标头参数中提供正确的内容类型。 有关标题字段的参考,您可以看到: - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

查看服务的响应内容类型并请求相同的服务。