7

I'm having a simple jquery ajax call to a rest service. I am setting the contentType as "application/json" and the rest resource is configured to accept "MediaType.APPLICATION_JSON". This is a POST method. With this setup, I am getting "Unsupported Media Type" error.

The header info shows "Content-Type application/json; charset=UTF-8" in the request header

Response shows: Status report: Unsupported Media Type The server refused this request because the request entity is in a format not supported by the requested resource for the requested method (Unsupported Media Type).

Please provide some pointers to resolve this issue.

Here is the code snippet:

Rest Resource

@POST
@Produces({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML})
@Consumes({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML})
public Response addPerson(MyJSONObj myObj) {
    //...  
    // ...
    //...
}

jquery

$(document).ready(function() { /* put your stuff here */
    $("#Button_save").click(function(){
    var firstName = $('firstName').val(); 
    var lastName = $('lastName').val(); 
    var person = {firstName: firstName, lastName: lastName}; 
    $.ajax({

        url:'http://localhost:8080/sampleApplication/resources/personRestService/',
        type: 'POST',
        data: person,
        Accept : "application/json",
        contentType: "application/json",

        success:function(res){
        alert("it works!");
        },
        error:function(res){
            alert("Bad thing happend! " + res.statusText);
        }
    });
    });
}); 

Headers as displayed in FF Firebug

Response Headers

Content-Length  1117
Content-Type    text/html;charset=utf-8
Date    Thu, 05 Apr 2012 09:44:45 GMT
Server  Apache-Coyote/1.1

Request Headers

Accept  */*
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Connection  keep-alive
Content-Length  97
Content-Type    application/json; charset=UTF-8
Host    localhost:8080
Referer http://localhost:8080/sampleApplication/
User-Agent  Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0
X-Requested-With    XMLHttpRequest
RJ.
  • 313
  • 2
  • 5
  • 14

4 Answers4

6

i had the same problem and I was able to solve it that way (see http://www.weverwijk.net/wordpress/tag/jquery/):

$.ajax({
    url:'http://localhost:8080/sampleApplication/resources/personRestService/',
    type:'POST',
    data: JSON.stringify(person),
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    success:function(res){
        alert("it works!");
    },
    error:function(res){
        alert("Bad thing happend! " + res.statusText);
    }
});

On Java side I added these (see Access-Control-Allow-Origin ):

@OPTIONS
public Response testt(@Context HttpServletResponse serverResponse) {
    serverResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    serverResponse.addHeader("Access-Control-Allow-Credentials", "true");
    serverResponse.addHeader("Access-Control-Allow-Origin", "*");
    serverResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
    serverResponse.addHeader("Access-Control-Max-Age", "60");
    return Response.ok().build();
}

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
public Response addPerson(MyJSONObj myObj, @Context HttpServletResponse serverResponse)
    serverResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    serverResponse.addHeader("Access-Control-Allow-Credentials", "true");
    serverResponse.addHeader("Access-Control-Allow-Origin", "*");
    serverResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
    serverResponse.addHeader("Access-Control-Max-Age", "60");

    // ...
    // ...
} 

Conclusion

Tobias Sarnow
  • 1,076
  • 2
  • 12
  • 40
1

I think the original post would have worked had the code done two additional things:

set the data to JSON.serialize(person) and set the dataType to 'json' since the contentType was correct, this should work with the @PUT expecting to consume json...

wnm3
  • 381
  • 3
  • 17
0

It looks like you may be suffering from a leaky abstraction. See this response: JQuery's getJSON() not setting Accept header correctly?

If you're doing a cross-domain call, then it seems you are not able to set the accept header due to how jQuery abstracts the call from you.

You do say that the server is seeing the correct accept header, though. That could be indicating a different issue.

Community
  • 1
  • 1
GrooveStomp
  • 374
  • 3
  • 18
0

TRY THIS FIRST Convert your data to JSON format as @wnm3 suggested.

IF STILL FACING PROBLEM CONTINUE -

This helped me, if your Request syntax is correct. This is the thing I did which remove the 415 Unsupported error -

@PUT
//REMOVE THIS LINE !!!!!! ----- @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response addPerson(MyJSONObj myObj)

  //
  //Your code here
  return Response.ok()
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD")
            .header("Access-Control-Allow-Headers", "Content-Type,Accept,X-Requested-With,authorization")
            .header("Access-Control-Allow-Credentials", true)
            .build();
} 

I exactly don't know, how to make CORS request which will send and accept application/json. The answer given by @Tobias Sarnow is partially incorrect. As you don't need method which accepts OPTIONS request. Even if the browser is showing that it sends OPTIONS request, it will still look for method with @POST annotation. So instead of putting up a filter or doing something else(more refined ways) I did through quick fix by using another method with no @Consumes and @Produces. Example-

@PUT
public Response addPerson() {
    return Response.ok()
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD")
            .header("Access-Control-Allow-Headers", "Content-Type,Accept,X-Requested-With,authorization")
            .header("Access-Control-Allow-Credentials", true)
            .build();
}

@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response addPerson(MyJSONObj myObj)
  //
  //Your code here
  //
  return Response.ok()
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD")
            .header("Access-Control-Allow-Headers", "Content-Type,Accept,X-Requested-With,authorization")
            .header("Access-Control-Allow-Credentials", true)
            .build();
} 

So what's happening here is as initial CORS for OPTIONS is handled by first method then the second method handles the original PUT request.

I am putting this answer here as it took me 3-4 days to figure out why my PUT request was not going through. So it may help someone who is having 415 error.

Saurabh Gupta
  • 363
  • 3
  • 6
  • 17