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

Exception in thread "main" javax.ws.rs.NotAcceptableException: HTTP 406 Not Acceptable

我在执行 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

在网络浏览器上(当 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>

这是执行的 TodoResourceClient:

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


}

来自控制台的堆栈跟踪:

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.access0(JerseyInvocation.java:91)
    at org.glassfish.jersey.client.JerseyInvocation.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>

Http Status Codes

406 Not Acceptable

The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.

.accept(mediatype) 是为请求设置 Accept header 的原因。您目前有五个请求,每个请求接受不同的类型

MediaType.TEXT_PLAIN,MediaType.TEXT_HTML, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON

这是 Content-Negotiation 在工作。服务器端配置是使用 @Produces(与 Accept header 一起)和 @Consumes(与 Content-Type header).

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

MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON

上面加粗的是缺失的。删除那些,如果所有其他都是正确的,这应该适合你。

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

两者都

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

检查您的内容类型!

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