0

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

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

8
  • Accept: application/json Content-Type: application/json This is what the client should have Commented May 10, 2017 at 8:26
  • Where do you want me to put this ? Commented May 10, 2017 at 8:27
  • @saurav put a header Accept with value application/json Commented May 10, 2017 at 8:28
  • i have already put in the request mapping annotation Commented May 10, 2017 at 8:29
  • A couple of question: server-side: wich kind of spring viewresolver are you using?. Client-side: how are you invoking your rest service? Commented May 10, 2017 at 9:19

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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) {

        }

    });
}

2 Comments

Did not help...i am getting equest processing failed; nested exception is java.lang.IllegalArgumentException: Invalid token character ' ' in token "Content-Type = application"...most probably due to supportedmediatypes property
Oh. sorry. you want request body json string. i got it. change my code. try one more.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.