Chandu D Chandu D - 1 month ago 7
reST (reStructuredText) Question

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

I get the following exception when I execute the REST Client :

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


On web browser( when tomcat is running), the URL : http://localhost:8080/com.dcr.jersey.first/webapi/todo gives output

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


But running the client code throws the exception, what is the mapping that's missing here?, appreciate your guidance( included all code samples)

Here is the 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>


Here is the TodoResourceCliient executed:

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


}


Stacktrace from Console :

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)


Dependencies included from pom.xml: am I missing any dependencies ?

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

Answer

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

The .accept(mediatype) is what set the Accept header for the request. You currently have five requests, each accepting a different type

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

This is Content-Negotiation at work. The server side configuration of this is with the use of the @Produces (which goes in hand with the Accept header) and @Consumes(which goes in hand with the Content-Type header).

That being said, look at all your @Produces annotations. You currently only support the producing of media types

MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON

The missing ones are in bold above. Remove those, and given all else is correct, this should work for you.