简体   繁体   English

在Spring中使用ResponseBody注释返回Json无法正常工作

[英]Using ResponseBody annotation in Spring for returning a Json not working

I am working on a spring mvc web application, in which I am using Google Visualization API for generating some charts. 我正在开发一个spring mvc web应用程序,我正在使用Google Visualization API生成一些图表。 I have a model class which contains 2 arraylists, which represent the data that I`m sending to the function that draws the chart (this is what i want to be converted to a JSON). 我有一个模型类,其中包含2个arraylists,它们表示我发送到绘制图表的函数的数据(这是我想要转换为JSON的)。

The model class: 模型类:

@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;
}
}

Then I ve got a @Component` annotated class which contains a method that returns a model object (of the class that I wrote above), with the 2 arraylists attributes populated. 然后我ve got a @Component注释类,它包含一个返回模型对象(我上面写的类)的方法,并填充了2个arraylists属性。

@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;}
}

So the Controller class, the one that has the mapping for the action that I am calling to gather data for the chart generation and in which I am calling listPieChartData method, from the class above, and in which I'm also using the @ResponseBody annotation is this: 那么Controller类,我正在调用的动作映射,用于为图表生成收集数据,我从上面的类中调用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 ); }

The JavaScript function that draws the chart : 绘制图表的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);

} }

And the AJAX call to the controller's mapped method (for gathering data) that finally calls the above JS function to obtain the chart (I'm also sending the request param int id for the controller method , I didn't wrote that) 并且AJAX调用控制器的映射方法(用于收集数据),最终调用上面的JS函数来获取图表(我也是为控制器方法发送请求param 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);
    }
    });  
});

I know this is a lot of code :) but it's pretty simple code, to understand the flow better, here is how it`s working: 我知道这是很多代码:)但它是非常简单的代码,更好地理解流程,这是它的工作方式:

From a button input I'm calling, with AJAX, the mapped method to the drawPieChart action (which is in the ChartController class), this methods sends the response through invoking the listPieChart method (from the ChartUtils class), which returns a JsonResponse object, (which contains 2 arraylists). 从一个按钮输入我用AJAX调用drawPieChart操作的映射方法(在ChartController类中),这个方法通过调用listPieChart方法(来自ChartUtils类)发送响应,该方法返回一个JsonResponse对象,(包含2个arraylists)。 This JsonResponse should be converted to a JSON, because in the AJAX request, I'm telling that the request needs a JSON input (via contentType: "application/json"), and it should get it because I use @ResponseBody in the controller method mapped for this request. 这个JsonResponse应该转换为JSON,因为在AJAX请求中,我告诉请求需要一个JSON输入(通过contentType:“application / json”),它应该得到它,因为我在控制器中使用@ResponseBody为此请求映射的方法。

I`m getting this response: 我收到了这个回复:

The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers (). 此请求标识的资源只能根据请求“accept”headers()生成具有不可接受特征的响应。
(HTTP Status 406) (HTTP状态406)

Please correct me where I'm wrong, I just can't get this working and I can't figure out why... 请纠正我错在哪里,我不能让这个工作,我无法弄清楚为什么......

And my servlet-context.xml : 我的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>

So the problem was that i didn'd have all the Jackson dependencies declared in pom.xml. 所以问题是我没有在pom.xml中声明所有Jackson依赖项。 These are the dependencies for your maven project in case you want Spring 3 to automatically serialize an object for you , using the @ResponseBody annotation , as a response from a method. 这些是您的maven项目的依赖项,以防您希望Spring 3使用@ResponseBody注释自动为您自动序列化对象,作为方法的响应。 Noob stuff , but I didn't saw this mentioned in the examples that I found . Noob的东西,但我没有在我找到的例子中看到过这个。

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

Also , I had to change some stuff in the ajax call for invoking the method that is returning the json object with data for the chart generation : 另外,我不得不在ajax调用中更改一些东西,用于调用返回json对象的方法,该方法包含图表生成的数据:

$("#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);
        }
    });

});

I'm accessing the data in the Json object that I`m getting as a response from the call with data.percentages , data.topics . 我正在访问Json对象中的数据,我将通过data.percentages,data.topics调用来获取响应。

A small update for the world of 2015: 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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