Spring入门遇到的坑----后端接受json并自动匹配转换实体

在springmvc中 可以接受前端传来的json数据 并自动在后端映射为相应的实体
例如 在下面这段代码中 可以将页面传来的json数据匹配成map

@RequestMapping(value = "/jsonMap")
    public Void jsonMap(@RequestBody Map<String,List<User>> userListMap){
     List<User> userList = userListMap.get("userList");
        for(User user :userList){
            System.out.println(user.toString());
        }
        
    }

但是在这个过程中 ,对初学者来说,由于很多概念都不清楚 ,所以存在着很多坑。在此总结下这个过程中需要注意的地方,并会在文章中引入一些比较好的参考文章。

在这个过程中可能遇到的错误code有
404、415、500…等,下面描述了什么情况下会出现什么问题

首先假设我们有个User对象 需要在前端传来一个user列表并与user实体相对应

//Java 
public class User  {
    String userName;
    String pwd;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
   }

Spring入门遇到的坑----后端接受json并自动匹配转换实体
在前端页面 录入一个测试数据 并循环几遍 组装成一个list
前端代码如下:

$("#login").bind("click",function(){
    		var userName = "";
    		var pwd = "";
    		userName = $("#login-username").val();
    		pwd = $("#login-password").val();
            var userList = [];
            for(var i = 0;i<10;i++){
                userList.push(new user(userName,pwd));
            }
    		$.ajax({
    			type:"POST",
    			url:"home/jsonMap",
				contentType:"application/json",
    			data:JSON.stringify({
    				'userList':userList
    			}),
    			success:function(data){
    				alert(data);
    			},
    			error:function(){
    				alert("失败!");

    			}
    		});
    	});
    	function user(userName,pwd) {
    	    this.userName = userName;
    	    this.pwd = pwd;

        }

组装好的json数据为

{"userList":[{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"},{"userName":"123","pwd":"123"}]}

以下开始罗列有可能遇到的问题
一、前端问题
1.ajax请求忘写 contentType:"application/json"
在此需指定传输的数据类型为 json数据 否则请求会出现 415 错误
Spring入门遇到的坑----后端接受json并自动匹配转换实体
2.json数据未用JSON.stringify()函数处理
该函数将对象转换为json字符串,若不将数据进行转换 会出现400错误。 主要是传到后端的数据必须为json字符串
Spring入门遇到的坑----后端接受json并自动匹配转换实体
对该函数的用法可参考下面的文章,讲的很仔细

https://www.cnblogs.com/tugenhua0707/p/9800453.html

二、后端问题

若前端代码写的都没问题 接下来就可以排查后端问题了

@RequestMapping(value = "/jsonMap")
    public String jsonMap(@RequestBody Map<String,List<User>> userListMap)

Controller 函数中 需要有两个注解 @RequestMapping @RequestBody
第一个对请求url进行映射 需要注意的是需要配置<context:component-scan base-package="com.Controller"></context:component-scan>扫包 否则会出现请求404问题,映射的url访问不到。
第二个注解@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。
通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上
GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,需要用POST方式进行提交。

对于@RequestBody注解的使用可以参考下面的文章
1.简单了解并使用

https://www.cnblogs.com/qiankun-site/p/5774300.html

2.详细了解参考

https://blog.csdn.net/justry_deng/article/details/80972817

回到正题,如果你后端代码中正确写了所有注解 那么你可能还会遇到404问题
Spring入门遇到的坑----后端接受json并自动匹配转换实体
原因是你虽然正确使用了注解,但是你并没有注册开启该注解的bean
解决办法是 配置 <mvc:annotation-driven />(+引入对应的jackson包)

<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
但是因为你配置了 <context:component-scan />,所以请求还是会被正确分发,你还是能访问到映射的url 但是json参数确还是不能被正确接受并映射到相应实体
因为 <mvc:annotation-driven />还提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)
我们使用ajax就使用到了对json的支持,此时,我们就可以正确接受json数据并映射到相应实体了
但是我们还需要引入jackson包,引入时需要注意spring与jackson的版本是否匹配

<mvc:annotation-driven />相关的文章如下

https://www.cnblogs.com/dreamroute/p/4493346.html

https://www.jfh.com/jfperiodical/article/3463

两个描述的都很好 建议按顺序看

至此 这个问题就描述的差不多了,如果还没有解决你的问题 建议你去看一下下面的这篇文章 , 如果你的问题解决了 也强烈建议你去看一下这篇文章。文章里还描述了其他参数传递的方法 ,以及代码案例。看完参数传递这块就差不多了。

https://blog.csdn.net/yixiaoping/article/details/45281721#comments