在Spring框架中使用ResponseBody注解返回Json无效。

3
我正在开发一个使用Spring MVC框架的Web应用程序,在其中我使用Google Visualization API来生成一些图表。我有一个模型类,其中包含两个ArrayList,它们代表我要发送到绘制图表函数的数据(这就是我想转换为JSON的内容)。
模型类如下:
@Component
public class JsonResponse {

private List<Integer> percentages = new ArrayList<Integer>();
private List<String> topics = new ArrayList<String>();

public JsonResponse(){
}

public List<Integer> getPercentages() {
    return percentages;
}

public void setPercentages(List<Integer> percentages) {
    this.percentages = percentages;
}

public List<String> getTopics() {
    return topics;
}

public void setTopics(List<String> topics) {
    this.topics = topics;
}
}

然后,我有一个被`@Component`注解的类,其中包含一个方法,该方法返回一个模型对象(上面我编写的类的对象),并填充了两个ArrayList属性。
@Component
public class ChartUtils {
    @Autowired
    public JsonResponse response;

    public JsonResponse listPieChartData( ModelAndView model ,int waveId ){

    //arraylists for chart generation
List<Integer> percentages = new ArrayList<Integer>();
List<String> topics = new ArrayList<String>();

    {... code for accessing the DB and processing some data and then populating the 2                  
     arraylists ... }

response.setTopics(topics);
response.setPercentages(percentages);

return response;}
}

所以控制器类,也就是拥有我正在调用以收集图表数据的操作映射,并在其中调用上面的类中的listPieChartData方法的那个类,同时我还使用了@ResponseBody注释,它是这样的:
@Controller
public class ChartController {

@Autowired
public ChartUtils utils;

@Autowired
public JsonResponse response;

@RequestMapping(value = "/drawPieChart", method = RequestMethod.GET )
@ResponseBody
public JsonResponse drawPieChart( ModelAndView model,
        @RequestParam(value = "id", defaultValue = "-1") int waveId ) {

    return utils.listPieChartData(model,waveId ); }

绘制图表的JavaScript函数:
function drawColumnChart(percentages, topics , div,width,height) {
    var data = new google.visualization.DataTable();

data.addColumn('string', 'Wave');
for (var i=0; i < topics.length; i++){
    data.addColumn( 'number', topics[i] ); 
}

    data.addRow( percentages );

    var wave=percentages[0];
    var options = {
        'title':'Generated Chart For '+wave,
        'backgroundColor': { fill: "none" },
        'is3D': true,
        'width':width,
        'height':height,
    };

var chart = new google.visualization.ColumnChart(document.getElementById(div));
chart.draw(data, options);

这段文字的意思是:在AJAX调用控制器映射方法(用于收集数据)后,最终调用上述JS函数以获取图表(我还向控制器方法发送请求参数int id,但我没有写那部分代码)。
$("#button").live("click", function(){

var arrayP, arrayT;
$.ajax({
    url: "drawPieChart",      
contentType: "application/json",
data: params,
success: function(data) {
    $.each(data, function(messageIndex, message) {
    if (messageIndex === 0) {
            arrayP = message;
    } else {
    arrayT = message;
    }
        });
    drawPieChart(arrayP, arrayT,'chart_div',600,400);
    }
    });  
});

我知道这是很多代码 :) 但它是相当简单的代码,为了更好地理解流程,以下是它的工作原理:

从按钮输入中,我使用 AJAX 调用映射到 drawPieChart 操作的方法(该方法位于 ChartController 类中),此方法通过调用 listPieChart 方法(来自 ChartUtils 类)发送响应,该方法返回一个 JsonResponse 对象(其中包含 2 个 arraylist)。这个 JsonResponse 应该被转换为 JSON,因为在 AJAX 请求中,我告诉请求需要一个 JSON 输入(通过 contentType: "application/json"),并且它应该得到它,因为我在控制器方法中使用了 @ResponseBody。

我得到了这个响应:

根据请求“接受”标头 (),此请求标识的资源只能生成不符合要求的响应特性。
(HTTP状态码 406)

请纠正我错误的地方,我无法让它工作,也找不出原因...

还有我的 servlet-context.xml 文件:

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

  <!-- DispatcherServlet Context: defines this servlet's request-processing      
infrastructure -->

  <!-- Enables the Spring MVC @Controller programming model -->
  <annotation-driven />

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

  <!-- Resolves views selected for rendering by @Controllers to .jsp resources
    in the /WEB-INF/views directory -->
  <beans:bean 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
  </beans:bean>

  <context:component-scan base-package="com.bla.bla" />

  <beans:import resource="classpath:springJDBC.xml" />

</beans:beans>

将produces="application/json"添加到您的@RequestMapping有帮助吗? - arahant
嗨,我已经尝试了这个,结果还是一样的。我也使用了Firebug来检查请求,头部包含Content-Type为application/json,所以我真的不知道问题出在哪里... - Adrian Bob
在查看了该帖子的答案后,我没有任何Jackson bean或任何json映射在协商解析器中,因此如果这并没有帮助,我不认为这是一个重复的帖子。 - Adrian Bob
1
但是你的类路径中确实有Jackson吗? - Grzegorz Rożniecki
已添加Jackson依赖项,现在一切都正常了,谢谢Xaerxess。 - Adrian Bob
显示剩余2条评论
2个回答

4

问题在于我的pom.xml文件中没有声明所有的Jackson依赖项。以下是您的maven项目所需的依赖项,以便在使用@ResponseBody注释作为方法的响应时,让Spring 3自动为您序列化对象。这是入门级内容,但我在找到的示例中没有看到这个提到。

  <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.6.1</version>
    </dependency>

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

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

同时,我不得不更改调用返回图表生成数据的Json对象的方法的Ajax调用中的一些内容:

$("#buttonPieGenerate").live("click", function(){

    $.ajax({
        url: "drawPieChart", //method from controller
        contentType: "application/json",
        data: params,
        success: function(data) {

        drawPieChart(data.percentages, data.topics,'chart_div',600,400);
        }
    });

});

我正在访问从调用中获取的Json对象中的数据,这些数据是通过data.percentages、data.topics返回的响应。


3

2015年的一个小更新:

<dependency>
    <!-- Just placing this on the classpath will enable JSON for @ResponseBody -->
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接