关于java:Spring 3.0使用jackson消息转换器进行JSON响应

Spring 3.0 making JSON response using jackson message converter

我将messageconverter配置为杰克逊的

1
class Foo{int x; int y}

在控制器中

1
2
3
4
@ResponseBody
public Foo method(){
   return new Foo(3,4)
}

因此,我希望在不进行任何其他配置的情况下从服务器返回JSON字符串X:'3',Y:'4'。但是我的Ajax请求得到404错误响应

If the method is annotated with @ResponseBody, the return type is written to the response HTTP body. The return value will be converted to the declared method argument type using HttpMessageConverters.

我错了吗?或者,我应该使用序列化程序将响应对象转换为JSON字符串,然后将该字符串作为响应返回(我可以正确地进行字符串响应),还是应该进行其他配置?比如为类foo添加注释

这是我的conf.xml

1
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
1
2
3
4
5
6
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>


您需要以下内容:

  • 设置注释驱动的编程模型:将放入spring.xml
  • 将jaskson jar(maven artifactid是org.codehaus.jackson:jackson-mapper-asl)放在类路径中。
  • 使用如下:

    1
    2
    3
    4
    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public @ResponseBody Foo method(@Valid Request request, BindingResult result){
    return new Foo(3,4)
    }

  • 这对我有用。

    请注意:

  • @ResponseBody应用于返回类型,而不是方法定义。
  • 您需要@RequestMapping注释,以便Spring可以检测到它。

  • messageconverter接口http://static.springsource.org/spring/docs/3.0.x/javadoc-api/定义了getSupportedMediaTypes()方法,在映射的情况下,该方法将返回application/json

    1
    2
    3
    public MappingJacksonHttpMessageConverter() {
        super(new MediaType("application","json", DEFAULT_CHARSET));
    }

    我假设缺少accept:application/json请求头。


    这对我很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @RequestMapping(value ="{p_LocationId}.json", method = RequestMethod.GET)
    protected void getLocationAsJson(@PathVariable("p_LocationId") Integer p_LocationId,
         @RequestParam("cid") Integer p_CustomerId, HttpServletResponse response) {
            MappingJacksonHttpMessageConverter jsonConverter =
                    new MappingJacksonHttpMessageConverter();
            Location requestedLocation = new Location(p_LocationId);
            MediaType jsonMimeType = MediaType.APPLICATION_JSON;
            if (jsonConverter.canWrite(requestedLocation.getClass(), jsonMimeType)) {
            try {
                jsonConverter.write(requestedLocation, jsonMimeType,
                                       new ServletServerHttpResponse(response));
                } catch (IOException m_Ioe) {
                    // TODO: announce this exception somehow
                } catch (HttpMessageNotWritableException p_Nwe) {
                    // TODO: announce this exception somehow
                }
            }
    }

    请注意,该方法不返回任何内容:MappingJacksonHttpMessageConverter#write()具有魔力。


    HTTP 404错误只意味着找不到资源。可能有两个原因:

  • 请求URL错误(客户端错误或给定链接/按钮中的URL错误)。
  • 资源不在您期望的位置(服务器端错误)。
  • 要修复1,请确保使用或提供正确的请求URL(区分大小写!)。若要修复2,请检查服务器启动日志中是否存在任何启动错误,并相应地修复这些错误。

    这一切都超出了最远发布的代码和信息。


    我发现我也需要jackson-core-asl.jar,而不仅仅是jackson-mapper-asl.jar


    除了这里的答案……

    如果您在客户端使用jquery,这对我很有用:

    爪哇:

    1
    2
    @RequestMapping(value ="/ajax/search/sync")
    public ModelAndView sync(@RequestBody Foo json) {

    jquery(您需要包括Douglas Crockford的json2.js才能具有json.stringify函数):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $.ajax({
        type:"post",
        url:"sync", //your valid url
        contentType:"application/json", //this is required for spring 3 - ajax to work (at least for me)
        data: JSON.stringify(jsonobject), //json object or array of json objects
        success: function(result) {
            //do nothing
        },
        error: function(){
            alert('failure');
        }
    });


    我想404和你的httpmessageconverter没有关系。我有同样的404问题,原因是我忘记了只有匹配的请求被发送到Dispatcherservlet(我将请求映射从*.do更改为*.json)。也许这也是你的情况。


    这只是一个猜测,但默认情况下,杰克逊只自动检测公共字段(和公共getter;但不管可见性如何,所有setter)。如果需要的话,还可以将此配置(使用版本1.5)以自动检测私有字段(请参见此处了解详细信息)。