8

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>
Alferd Nobel
  • 3,185
  • 2
  • 30
  • 35

3 Answers3

8

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.

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Thanks for clearing that out. As pointed I commented the bolded MediaType. When I run the code I get a Http 500 ( Internal server exception ) . This is what I did : – Alferd Nobel Apr 05 '15 at 18:44
  • When I run the code I get a Http 500 ( Internal server exception ) . The MediaType.TEXT_XML got executed "successfully" . The MediaType.APPLICATION_JSON throws : [Exception in thread "main" javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1002)] Am I missing any jars that has to be added to my maven pom.xml? – Alferd Nobel Apr 05 '15 at 18:55
  • Sorry but you will need to post the stack trace for further help. As for any other jars, if you don't already have one, for JSON support, use [this](https://jersey.java.net/documentation/latest/media.html#json.jackson). – Paul Samsotha Apr 05 '15 at 21:13
  • Please update your post. Do not put all this stuff in comments. If you added new code, then update your post with that also – Paul Samsotha Apr 06 '15 at 01:00
  • I fixed the Internal Server Error(updated post with the stacktrace) by adding the json dependency in pom file. I then added the mediatypes MediaType.TEXT_PLAIN,MediaType.TEXT_HTML to my TodoResource.java (updated the post ) . Once again landed with the same Internal Server Error. Which means, i'm missing more dependencies in pom.xml? (updated post with the pom.xml dependencies and the stack-trace ) – Alferd Nobel Apr 06 '15 at 03:53
  • Yeah so you can just add a `MediaType` to the `@Produces` annotation and it expect it to work. Internally, there are `MessageBodyReader`s and `MessageBodyWriter`s used to marshal and and unmarshal the request body to and from out POJO. How does the marshaller know how to turn your POJO into HTML. It doesn't, unless you create your own `MessageBodyWriter` (which is out of the scope of this conversation). Currently the only supported POJO to response writers you have are for JSON (moxy) and XML (included in framework) – Paul Samsotha Apr 06 '15 at 03:55
  • And I haven't tested, but I don't know if the writer that converts to XML, works with `TEXT_XML`. It might. But generally for XML, we use `APPLICATION_XML` (which for sure will work) – Paul Samsotha Apr 06 '15 at 03:57
  • If you want to learn more about readers and writers [see here](https://jersey.java.net/documentation/latest/message-body-workers.html) – Paul Samsotha Apr 06 '15 at 04:11
  • 1
    Thanks for being so quick . And that answers and it works fine for XML (both text and application XML ) and JSON. – Alferd Nobel Apr 06 '15 at 04:36
  • just curious , if both my resource method's have same MediaType signature for @Produces annotation( say `@Produces({ MediaType.APPLICATION_JSON } public Todo getXML()` and then `@Produces({ MediaType.APPLICATION_JSON } public Todo getHTML()` ), how will the client know which "method" to be called? – Alferd Nobel Apr 06 '15 at 04:49
  • The client doesn't call the method. Jersey internally looks at the `Accept` header, and chooses the correct `MessageBodyWriter` (for JSON or XML). If no `Accept` header is there, then it's a toss up for which one will be chosen. – Paul Samsotha Apr 06 '15 at 04:53
  • Actually I misread the question. I haven't tested, but I don't know if that will be allowed (meaning the app might not even load - as there is an initial "model validation"). It is too ambiguous. There's no way for Jersey to make the distinction, if there are using the same `@Path` – Paul Samsotha Apr 06 '15 at 04:55
1

Check your content type!

Setting to .accept(MediaType.TEXT_PLAIN) worked for me.

domih
  • 1,440
  • 17
  • 19
0

As correctly stated by peeskillet, your client calls with accept(MediaType.TEXT_PLAIN) and accept(MediaType.TEXT_HTML) will cause issues since your TodoResource methods do not specify these media types in the @Produces annotation.

Either

  1. change your TodoResource class to support these media types
  2. change your client code to remove the calls corresponding to these media types
Abhishek
  • 1,175
  • 1
  • 11
  • 21