SpringMVC自动转换后台数据格式为Json

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/flower_CSDN/article/details/81518819

刚开始后台是自己手动转换的json。前台接收后台的json数据时出现,Uncaught TypeError: Cannot read property ‘length’ of undefined

@ResponseBody
    @RequestMapping(value="newBookIndex",method=RequestMethod.POST)
    public JSONArray newBook() {
        Page<TBook> page=PageHelper.startPage(1, 4);//挑出最新的四条记录显示在首页
        List<TBook> newBookList=bookServ.orderByOnlineTime();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("newBookList", newBookList);
        System.out.println("newBookList"+newBookList.size());
        JSONArray json = net.sf.json.JSONArray.fromObject(map);
        return json;//返回当前页的图书
    }

后台的Ajax

function newBooks() {
    $.ajax({
        type : "post",
        url : "newBookIndex",//后台的action
        dataType : "json",//data : {},
        success : function(data) {
             if(data){
                 var res = []; 
                 jQuery.each(data.newBookList, function(i,book){
                     res.push('<div id="mbook" style="width: 20%;float: left; margin-left: 45px;">');
                     res.push('<img  src="img/girl.jpg" width="98%" height="345px" />');
                     res.push('<font>');
                     res.push('<br />');
                     res.push('<strong>&lt;&lt;'+book.name+'&lt;&lt;</strong>');
                     res.push('<br />作者:'+book.auth);
                     res.push('<br />分类:xxxxxx <br />更新时间:'+book.onlinetime);
                     res.push('<br />简介:'+book.brief);
                     res.push('</font>');
                     res.push('</div>');
                  });
                  $("#newBooks").empty().html(res.join(""));


           }
        },
        error : function() {
            alert("系统错误!");
        }
    });
}

Uncaught TypeError: Cannot read property ‘length’ of undefined
我猜可能是data.newBookList这个没有获取到。怀疑是数据格式的问题,后来在前台改成了JSON.parase(data.newBookList)还是有问题。然后又改回去。然后看网上有的在后天直接就用的map没有转换成json的格式,抱着试试的心态试了试,没想到居然成功了。简直神奇!

其实是因为Spring MVC的自动转换机制。
@ResponseBody是一种转换机制,在使用@ResponseBody注解之后,Controller返回的对象 就会自动被转换成对应的json数据,其实是因为spring-mvc.xml中的配置:。导致了java对象自动转换成json对象的现象。但前提是在转换之前我们已经添加了json数据转换的相关jar包,才能使json成为默认转换器之一,这样在转换数据过程中,转换器就会自动寻找相应的默认转换器。

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

不过我这算是误打误撞了,之前自己手动转的时候加了jar包,所以去掉说的那个转的代码之后,我的jar包还是可用的,所以自动转的时候并没有出现异常。

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.5</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>

关于SpringMVC对于Json的自动转换的原理和源码分析可以看这篇博客,写的很细致。
https://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html
@ResponseBody这个注解就是使用消息转换机制,最终通过json的转换器转换成json数据的。
在加入了这句配置以后分别实例化了RequestMappingHandlerMapping,ConfigurableWebBindingInitializer,RequestMappingHandlerAdapter等诸多类。
其中RequestMappingHandlerMapping和RequestMappingHandlerAdapter这两个类比较重要。
RequestMappingHandlerMapping处理请求映射的,处理@RequestMapping跟请求地址之间的关系。
RequestMappingHandlerAdapter是请求处理的适配器,也就是请求之后处理具体逻辑的执行,关系到哪个类的哪个方法以及转换器等工作,
RequestMappingHandlerAdapter设置messageConverters的逻辑。
我们可以在通过配置子节点message-converters的属性来配置转换器
message-converters的子节点配置如下

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="org.example.MyHttpMessageConverter"/>
    <bean class="org.example.MyOtherHttpMessageConverter"/>
  </mvc:message-converters>
</mvc:annotation-driven>

所以在没有配置子节点的时候,它会自动去找默认的转换器。

如果需要将数据转换成xml格式也是可以的,默认的转换器是支持XML的。我们只需要在需要转换的实体类上加上注解@XmlRootElement
消息转换器是根据class和mediaType决定的。
所以也可以设置http请求头中accept的类型 “Accept”: “application/xml”或者 “Accept”: “application/json”

.ajax({      url: “ {request.contextPath}/employee/xmlOrJsonSimple”,
success: function(res) {
console.log(res);
},
headers: {
“Accept”: “application/xml”
}
});
另外如果不想使用默认的RequestMappingHandlerAdapter。也可以自己配置,具体的还请参考https://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html

猜你喜欢

转载自blog.csdn.net/flower_CSDN/article/details/81518819
今日推荐