Parag
Parag

Reputation: 379

Jquery Ajax throws Error 406--Not Acceptable in Spring MVC

I am calling a controller method using Jquery AJAX. My controller method is called properly but ajax returns error = Error 406--Not Acceptable.

I have looked at other posts and following all the necessary steps. Am I missing something more?

I am using jackson-core-asl-1.9.4.jar jackson-mapper-asl-1.9.4.jar with spring 3.2

My spring-servlet.xml has following

<context:component-scan  base-package="org.lacare.frc.controller" />  
<mvc:annotation-driven></mvc:annotation-driven> 
<context:annotation-config/> 

My JSP has following ajax call

$.ajax({
      url: '<c:url  value="getServiceCategoriesForVisitType.html"/>' + '?visitTypeCode=' +$(this).val(),
      data: "",
      type: "GET",
      contentType: "application/json",
      dataType:"json" , 
      success: function(respContent) {

       alert(respContent); 

       },
       error:function( jqXHR,  textStatus,  errorThrown ){
            alert('error '+errorThrown);
                    }
        });  

My Controller method is as follows

   @RequestMapping(value={"/getServiceCategoriesForVisitType"},method=RequestMethod.GET,headers="Accept=*/*",produces = "application/json")
   public @ResponseBody List<String> loadreateVisitType(HttpServletRequest request,@RequestParam(value="visitTypeCode", required=true) long visitTypeCode) {    

    List<String> serviceCategories1=new ArrayList<String>();   
    serviceCategories1.add("abc"); 
    serviceCategories1.add("pqr"); 
    return serviceCategories1; 

   }

Upvotes: 1

Views: 13608

Answers (4)

Trideb Chapagai
Trideb Chapagai

Reputation: 59

The issue here is that the path value="getServiceCategoriesForVisitType.html" is going to use content negotiation first before checking the value of an Accept header. With an extension like *.html, Spring will use a org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy and resolve that the acceptable media type to return is text/html which does not match what MappingJacksonHttpMessageConverter produces, ie. application/json and therefore a 406 is returned.

OR

Following Maven dependency could be help if there is version issue with jackson :

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.5.1</version> 
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.5.1</version>
</dependency>

Upvotes: 0

Pierre
Pierre

Reputation: 2912

Try changing your method to return a String and, within your method, transform your list into a JSON String. For that, you could use google-gson but, given that we're playing with spring already and probably already have those dependencies in the project, you can use Jackson's ObjectMapper. like this:

       @RequestMapping(value={"/getServiceCategoriesForVisitType"},method=RequestMethod.GET,headers="Accept=*/*",produces = "application/json")
   public @ResponseBody String loadreateVisitType(HttpServletRequest request,@RequestParam(value="visitTypeCode", required=true) long visitTypeCode)
throws JsonProcessingException {    
    // NOTE1: change the method to return a "String"
    // NOTE2: add "throws JsonProcessingException" to the method (or catch it)
    List<String> serviceCategories1=new ArrayList<String>();   
    serviceCategories1.add("abc"); 
    serviceCategories1.add("pqr"); 
    //return serviceCategories1; 
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(serviceCategories1);
   }

Also add these 2 imports:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

I'm pretty sure the above will fix it for you. But just to make sure this answer is complete (if someone else comes up to this questions about the 406 error), the other thing to try is to add this to the @RequestMapping (you've already added that to your method so maybe a note for others):

headers="Accept=*/*",produces = "application/json"

ex:

@RequestMapping(value={"/getServiceCategoriesForVisitType"},method=RequestMethod.GET,headers="Accept=*/*",produces = "application/json")

Upvotes: 1

Jimmy
Jimmy

Reputation: 1875

You are just required to add:

@ResponseStatus(HttpStatus.OK)

Just below the:

@RequestMapping(value={"/getServiceCategoriesForVisitType"},method=RequestMethod.GET,headers="Accept=*/*",produces = "application/json")  

I was also facing the same error. This is an answer.

Upvotes: 4

lesssugar
lesssugar

Reputation: 16191

May be a header issue. Try adding this to your $.ajax():

headers: { 
    Accept : "application/json"
}

Upvotes: 2

Related Questions