1

I want to response JSON object or array from Spring MVC controller. From these two beingjavaguys and mkyoung tutorial, i tried. I could success only in when the response is string. But when the response is in object or in list, it doesn't work for me.

//It works
@RequestMapping(value = "/angular", method = RequestMethod.GET)
public @ResponseBody String getAllProfiles( ModelMap model ) {
String jsonData = "[{\"firstname\":\"ajitesh\",\"lastname\":\"kumar\",\"address\":\"211/20-B,mgstreet\",\"city\":\"hyderabad\",\"phone\":\"999-888-6666\"},{\"firstname\":\"nidhi\",\"lastname\":\"rai\",\"address\":\"201,mgstreet\",\"city\":\"hyderabad\",\"phone\":\"999-876-5432\"}]";
return jsonData;
}

Output is: enter image description here

But the problem is in it,

@RequestMapping(value = "mkyoung", method = RequestMethod.GET)
    public @ResponseBody Shop getShopInJSON() {

        Shop shop = new Shop();
        shop.setName("G");
        shop.setStaffName(new String[] { "mkyong1", "mkyong2" });
        return shop;
    }

It shows,

HTTP ERROR 406

Problem accessing /mkyoung.html. Reason:

    Not Acceptable

But if i change it toString() , It works but not with right output

@RequestMapping(value = "mkyoung", method = RequestMethod.GET)
public @ResponseBody String getShopInJSON() {

    Shop shop = new Shop();
    shop.setName("G");
    shop.setStaffName(new String[] { "mkyong1", "mkyong2" });
    return shop.toString();

}

enter image description here

But i need JSON object or array of object as response. What is the probelm ? I have added jsckson dependency in my pom.xml

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

UPDATE: Now i am sending request from angular js by adding

headers: {
                "Content-Type": "application/json"
            }

My dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <mvc:annotation-driven />

    <context:component-scan base-package="com.sublime.np.controller" />

    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/defs/general.xml</value>
            </list>
        </property>
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.tiles3.TilesView" />
    </bean>

</beans>

As Sotirios Delimanolis's Answer suggesion.

$http({
            url: '/mkyoung.html',
            method: 'GET',
            data: id,
            headers: {
                "Content-Type": "application/json"
            }
            }).success(function(response){
                $scope.response = response;
                console.log($scope.response);
               /*  $scope.hideTable = false;
                $scope.hideButton  = false ; */
            }).error(function(error){
                $scope.response = error;
                console.log("Failed");
        });

But it shows same error. enter image description here

1
  • Also, you can enable your DEBUG logs for Spring. They will explain what is going on. Commented Jun 3, 2015 at 16:14

2 Answers 2

2

Also add jackson core

<dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>2.5.1</version>
</dependency>

For List use method return type Object

@RequestMapping(value = "mkyoung", method = RequestMethod.GET)
    public @ResponseBody Object getShopInJSON() {

        Shop shop = new Shop();
        shop.setName("G");
        shop.setStaffName(new String[] { "mkyong1", "mkyong2" });
        Shop shop1 = new Shop();
        shop1.setName("G1");
        shop1.setStaffName(new String[] { "mkyong1", "mkyong2" });
        List<Shop> shops = new ArrayList<Shop>();
        shops.add(shop1);
        shops.add(shop);
        return shops;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Careful with this version of JACKSON! it is not compatible with newer version of spring (4.x i think). You have to use: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.1</version> </dependency>
1

Given @ResponseBody with a POJO type return type, a default MVC configuration with @EnableWebMvc or <mvc:annotation-driven />, and Jackson on the classpath, Spring will try to serialize the POJO to JSON and write it to the response body.

Since it's writing JSON, it's going to attempt to write application/json as the Content-type header. The HTTP specification requires that the server only responds with content types that are part of the Accept header in the request.

It seems you're sending your request with an inappropriate Accept header that doesn't contain application/json. Fix that.


Note that you are sending your request to

/mkyoung.html

Spring, by default, uses content negotiation based on some extensions. For example, with .html, Spring will think the request should produces text/html content, which is contrary to the application/json you want to send.

Since your handler is already mapped to

@RequestMapping(value = "/mkyoung", method = RequestMethod.GET)

just send the request to the corresponding URL, ending in /mkyoung. (Get rid of the .html extension.)

9 Comments

I have added <mvc:annotation-driven /> in my dispatcher-servlet.xml. And where can i add application/json?
@Romeo In your request. If you're just sending a GET request through your browser, you can't do it directly. Open your browser's network console, find your request, change its headers and resend it. Otherwise, use a different HTTP client.
@Romeo You said you had jackson 1 on the classpath? Can you also show us your configuration?
Yes. I have posted it. See just before the update part of this question.
@Romeo Oh. I just noticed you are sending your request to mkyong.html. I believe Spring uses default content negotiation based on some extensions, .html being one of them. Get rid of the .html extension. Your handler is mapped to /mkyoung anyway.
|

Your Answer

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