Pages

Wednesday, 19 March 2014

SOLVED: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

I have a controller which is used for a simple String list response using JSON for a jquery autocomplete scenario. On invoking the url got the warning mentioned below and no response was received on the ajax call.

The details of the configuration is as mentioned below:

Note : The request url ending with ".html" which turned out to be the cause of the issue

Jquery for Ajax invocation:

var classList = "<c:url value='/common/classlist.html' />";
$(function() {
    var cache = {};
    $( "#modelClass" ).autocomplete({
      minLength: 2,
      source: function( request, response ) {
        var term = request.term;
        if ( term in cache ) {
          response( cache[ term ] );
          return;
        }
 
        $.getJSON( classList, request, function( data, status, xhr ) {
          cache[ term ] = data;
          response( data );
        });
      }
    });
  });

Controller:

@RequestMapping(value="/common/classlist", method=RequestMethod.GET)
public @ResponseBody List listValidClass(@RequestParam("term") String className){
  .. Return List
}

Maven Dependency:

 
   <jackson.version>2.3.2<jackson.version>

    <dependency>
        <groupid>com.fasterxml.jackson.core</groupid>
        <artifactid>jackson-databind</artifactid>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupid>com.fasterxml.jackson.core</groupid>
        <artifactid>jackson-annotations</artifactid>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupid>com.fasterxml.jackson.core</groupid>
        <artifactid>jackson-core</artifactid>
        <version>${jackson.version}</version>
    </dependency>


Web.xml:


 <servlet-mapping>
  <servlet-name>simple-form</servlet-name>
  <url-pattern>*.html</url-pattern>
 </servlet-mapping>



Error:

java.util.List com.july11.web.mvc.admin.controller.ValidClassController.listValidClass(java.lang.String)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation 
Resolution:
The possible solutions mentioned were:
1) Ensure that jackson classes are present in the class path -- This was already present as the maven dependency was included.
2) Most of the solutions concentrated on jackson 1.x -- Tried including the 1.9.10 version and removing the fasterxml (2.x) from the maven dependency, but still the problem persisted.
3) A few of the suggestions cited that a List cannot be returned as a JSON -- Tried wrapping the response in an object with getters and setters for retrieving the list.
4) Include the jacksonMessageConverter in the xpring context -- This was slightly tricky as there were equal number saying that the <mvc:annotation-driven /> should take care of registering the appropriate convertor.
5) Modify the mvc:annotation driven configuration to register MappingJackson2HttpMessageConverter

After spending a lot of time finally decided to debug the request and for this started out with a breakpoint HttpMediaTypeNotAcceptableException for all exceptions which lead me to AbstractMessageConverterMethodProcessor from where the exception was being thrown. A bit of additional debug let me know that the response header content type was being mapped to "text/html" whereas spring was expecting the response content type recevied in request to match a json.



I double checked my request traffic on the browser where it was expecting a json response. Further debugs on ContentNegotiationManager and PathExtensionContentNegotiationStrategy.getMediaTypeKey finally gave me actual issue.

Issue And Final Resolution:
The request url had the extension as html which is mapped to content type of text/html by the DispatcherServlet. At this point all i had to do was either accept a request (without any extension) or be a bit more explicit and change my request url to "/common/classlist.json" from "/common/classlist.html".

Added the additional mapping in webx.xml to handle the url mapping and everything started working as expected.

 <servlet-mapping>
  <servlet-name>simple-form</servlet-name>
  <url-pattern>*.json</url-pattern>
 </servlet-mapping>


9 comments:

  1. Yeah, man, yeah! Thanks A LOT! I spent the whole day trying to find a solution. Great!

    ReplyDelete
  2. Thank you so much Ganaraj, I too spent the whole day trying to figure this out. No answer on stackoverflow fixed my issue. But your blog post did. Thanks again!

    ReplyDelete
  3. Thanks, the key was identifying that spring/jackson automatically assumes that a url ending with html cannot be a JSON type :)

    ReplyDelete
  4. Thanks. I could also resolve the issue.

    ReplyDelete
  5. Thanks so much for posting this. I had a request ending in a path variable that consisted of an email address. I had to add the :.+ to the end of the variable to get Spring not to truncate it, but then the return wasn't getting parsed. Since I had other similar functions working, I knew it had to be something in the variable. This post completely solve the issue. I dropped in a quick hack and just added an additional path item at the end that is ignored by my code but allows the processor to parse it correctly: e.g. the url changed from "/passwordReset/johndoe@mymail.com" to "/passwordReset/johndoe@mymail.com/reset". Everyhting then parses as intended.

    ReplyDelete
  6. Thanks a lot. I too struggled a lot and finally your blog helped me out. I was using .htm as action suffix.

    ReplyDelete
  7. Saved my nights. Thanks a lot.

    ReplyDelete