简体   繁体   中英

406 Not acceptable error when returning JSON in Spring MVC

I am working on application which will just used as a restful services and the response has to be returned as JSON.yp

I am on Spring MVC and following this article to achieve the same

https://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

I have added Jackson jar in my POM, enabled response body and mvc-annotation-driven annotation. But still on firing the url i get 406 Not acceptable error.

I have tried firing with a rest client and adding request headers for Content-Type and Accept with "application/json".

Below is my POM with the dependencies part

<!-- Spring 3 dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.10</version>
    </dependency>

My spring config file

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<mvc:annotation-driven />
<context:component-scan base-package="com.sap.cf.casestudy.controller" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

My controller code

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sap.cf.casestudy.domain.Employee;

@Controller
@RequestMapping("/employee")
public class EmployeeController {

    @RequestMapping(method = RequestMethod.GET ,headers="Accept=application/json")
    public @ResponseBody Employee getEmployee() {

        List<Employee> empList = getEmployeeData();
        return empList.get(0);


        //return "employeelist";

    }

    private List<Employee> getEmployeeData(){
        List<Employee> employeeList = new ArrayList<Employee>();
        Employee emp1 = new Employee();
        emp1.setFirstName("Saurav");
        emp1.setLastName("Sarkar");
        employeeList.add(emp1);

        Employee emp2 = new Employee();
        emp2.setFirstName("John");
        emp2.setLastName("Doe");
        employeeList.add(emp1);

        return employeeList;
    }

}

In addition i have a POJO of employee class with firstname and lastname as private methods and setter/getter as public methods.

Best Regards, Saurav

My simple setting. hope this helps a little bit

pom.xml

<!-- Jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.4.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.3</version>
</dependency>

servlet-context.xml

<!-- DispatcherServlet Context: defines this servlet's request-processing 
    infrastructure -->
<context:component-scan base-package="com.urong.sample" />

<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <beans:bean
            class="org.springframework.http.converter.StringHttpMessageConverter">
            <beans:property name="supportedMediaTypes">
                <beans:list>
                    <beans:value>text/html;charset=UTF-8</beans:value>
                </beans:list>
            </beans:property>
        </beans:bean>
        <beans:bean
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
    up static resources in the ${webappRoot}/resources directory -->
<mvc:resources location="/resources/" mapping="/resources/**" />
<mvc:default-servlet-handler />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
    in the /WEB-INF/views directory -->
<!-- Your Resolves -->

Controller

@RequestMapping(value = "/call", method = RequestMethod.POST)
public @ResponseBody String callTest(@RequestBody CompanyLocation location) {
    // use location. this sample object


    return "your return String";
}

client(my javascript)

function callTest() {
    var companyIdx = $('#companyIdx').val();
    var locationIdx = $('#locationIdx').val();

    var data = {
    idx : locationIdx,

    postCode : $('#postCode').val(),
    address : $('#address').val(),
    detailAddress : $('#detailAddress').val(),

    tel : $('#tel').val(),
    fax : $('#fax').val(),
    email : $('#email').val(),
    language : $("#language").val(),

    latitude : $('#latitude').val(),
    longtitude : $('#longtitude').val()

    };

    data = JSON.stringify(data);

    $.ajax({
        url : "/sample/call,
        type : 'POST',
        data : data,
        contentType : 'application/json',

        success : function(response) {

            // use response.

        },

        error : function(request, status, error) {

        },
        complete : function(data) {

        }

    });
}

I could resolve the problem with my above code itself.

Problem was the jackson mapper jar was not present in the classpath. So it was not working.

In Eclipse For Maven projects you have to force update such that the jar can come in the classpath.

Ideally there should been an error from the spring framework about the class not being loaded. The error itself was misleading.

Best Regards, Saurav

Spring 4.3.10: I used the below settings to resolve the issue.

Step 1: Add the below dependencies

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Step 2: Add the below in your MVC DispatcherServlet context configuration:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

<bean id="contentNegotiationManager"
        class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorPathExtension" value="false"/>
        <property name="favorParameter" value="true"/>
        <property name="ignoreAcceptHeader" value="false" />
    </bean>

Since spring 3.2, as per the default configuration favorPathExtension is set as true, because of this if the request uri have any proper extensions like .htm spring will give priority for the extension. In step 2 I had added the contentNegotiationManager bean to override this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM