基于SpringMVC接受JSON参数详解及常见错误总结
最近一段时间不想使用session了,想感受一下token这样比较安全,稳健的方式,顺便写一个统一的接口给浏览器还有app。所以把一个练手项目的前台全部改成ajax了,跳转再使用springmvc控制转发。对于传输json数据这边有了更深的一些理解,分享出来,请大家指正。
在springmvc中我们可以选择数种接受json的方式,在说springmvc如何接受json之前,我们先聊聊什么是json。具体的定义我也不赘述了,在javascript中我们经常这样定义json 对象
var jsonobject = { "username":"admin", "password":123 }
这种形式的我们叫它json对象,同时还有一个概念叫做json字符串,字符串呢,顾名思义,是由' ‘或者” “包裹起来的一个整体,我们称之为字符串。我们知道字符串是可以直接输出的,而对象不能直接输出。所以在javascript中,我们可以
//定义一个对象 jsonobject var jsonobject = { "username":"admin", "password":123 }; alert(jsonobject);
此时,会显示[object object]而不会输出json对象的内容,javascript向我们提供了两个工具
json.parse() 用于将一个 json 字符串转换为 javascript 对象。 json.stringify() 用于将 javascript 值转换为 json 字符串。
所以当我们输入
alert(json.stringify(jsonobject));
就会显示 {“username”:”admin”,”password”:123};
* 好了 对于json的讲解就到这里了 下面我们说一说springmvc *
既然json有着上述两种存在方式,那我们通过ajax向springmvc传值的时候,我们该传哪一种呢?
我们首先尝试直接发送json对象
//定义json对象 var username = $("#username").val(); var password = $("#password").val(); var json = { "username" : username, "password" : password }; // jquery ajax请求 $.ajax({ url : "jsontest", type : "post", async : true, data : json, datatype : 'json', success : function(data) { if (data.userstatus === "success") { $("#errormsg").remove(); } else { if ($("#errormsg").length <= 0) { $("form[name=loginform]").append(errormsg); } } } });
我们首先想想springmvc提供了什么给我们,有一个@requestparam的注解,对于这个注解,它的作用和我们servlet中的request.getparameter是基本相同的。我们首先使用这个注解来获取
@requestmapping("/jsontest") public void test(@requestparam(value="username",required=true) string username, @requestparam(value="password",required=true) string password){ system.out.println("username: " + username); system.out.println("password: " + password); }
后台成功输出的我们的参数,成功接受!
springmvc如此智能,如果我们去除@requestparam注解,直接将两个值放入会有什么后果?
@requestmapping("/jsontest") public void test(string username,string password){ system.out.println("username: " + username); system.out.println("password: " + password); }
竟然同样成功了,原理我这里就不多赘述了,有兴趣的朋友们可以打断点看看。
springmvc提供了一个@requestbody,它是用来处理前台定义发来的数据content-type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
细心的朋友们或许发现了,在之前的ajax中,我们没有定义content-type的类型,jquery默认使用application/x-www-form-urlencoded类型。那么意思就是springmvc的@requestparam注解,servlet的request.getparameter是可以接受到以这种格式传输的json对象的。
为什么呢!?get请求想必大家都不陌生,它将参数以url?username=”admin”&password=123这种方式发送到服务器,并且request.getparameter可以接收到这种参数,我们在浏览器地址栏上也可以看到这一点。而我们ajax使用的post,并且发送的是json对象,那么后台是如何获取到的呢?答案就在于这个content-type x-www-form-urlencoded的编码方式把json数据转换成一个字串,(username=”admin”&password=123)然后把这个字串添加到url后面,用?分割,(是不是和get方法很像),提交方式为post时候,浏览器把数据封装到http body中,然后发送到服务器。所以并不会显示在url上。(这段可能有点绕口,希望大家用心理解一下。)
终于说完了,长吐一口气。所以说我们使用@requestbody注解的时候,前台的content-type必须要改为application/json,如果没有更改,前台会报错415(unsupported media type)。后台日志就会报错content type ‘application/x-www-form-urlencoded;charset=utf-8' not supported,这些错误eclipse下tomcat是不会显示错误信息的,只有使用了日志才会显示,如何配置日志大家可以看我上一篇文章。接下来我们正确配置一下,上面说到了 content-type需要更改,同时我们的data也要更改了,这种注解方式只接受json字符串而不是json对象
$.ajax({ url : "jsontest", type : "post", async : true, contenttype : "application/json", data : json.stringify(json), datatype : 'json', success : function(data) { if (data.userstatus === "success") { $("#errormsg").remove(); } else { if ($("#errormsg").length <= 0) { $("form[name=loginform]").append(errormsg); } } } });
后台也更改一下,json其实可以理解为键值对嘛,所以我们用map接收,然后对字符串或者其他数据类型进行进一步处理。
@requestmapping("/jsontest") public void test(@requestbody(required=true) map<string,object> map ){ string username = map.get("username").tostring(); string password = map.get("password").tostring(); system.out.println("username: " + username); system.out.println("password: " + password); }
同时,我又想起了神奇的springmvc,所以我决定去掉注解试试,好的,果断被爆了一个空指针错误…尝试就此打住。
springmvc还提供了参数直接和pojo绑定的方法,我们来尝试一下。前台一样,就不贴出来了。
@requestmapping("/jsontest") public void test(@requestbody user user ){ string username = user.getusername(); string password = user.getpassword(); system.out.println("username: " + username); system.out.println("password: " + password); }
ok,这次是可以取到值的,我个人对于登录这类小数据量的上传来说不太喜欢这种方法,user里面的变量很多,我只用了其中两个,没有必要去创建一个user对象,一般数据量小的时候我还是比较喜欢使用单独取值出来的。我们再想一想,如果是在上传json对象的情况下,我们可不可以绑定pojo呢,答案是可以的,不要使用@requestparam注解,否则会报required user parameter 'user' is not present错误。到此讲解基本结束了,下面来总结一下。
我们首先说了json对象和json字符串
然后说了springmvc接受两种两种json格式的时候,前端contenttype的设定,和后端是否使用注解接受,还提到了一点servlet。
当ajax以application/x-www-form-urlencoded格式上传即使用json对象,后台需要使用@requestparam 或者servlet获取。 当ajax以application/json格式上传即使用json字符串,后台需要使用@rquestbody获取。
这是我实验了一天的一些总结,希望可以帮助到大家,如果有错误,请各位海涵并指正。
以上这篇基于springmvc接受json参数详解及常见错误总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。