转:https://blog.csdn.net/LostSh/article/details/68923874

SpringMVC接受JSON参数详解及常见错误总结

最近一段时间不想使用Session了,想感受一下Token这样比较安全,稳健的方式,顺便写一个统一的接口给浏览器还有APP。所以把一个练手项目的前台全部改成Ajax了,跳转再使用SpringMVC控制转发。对于传输JSON数据这边有了更深的一些理解,分享出来,请大家指正。

SpringMVC中我们可以选择数种接受JSON的方式,在说SpringMVC如何接受JSON之前,我们先聊聊什么是JSON。具体的定义我也不赘述了,在JavaScript中我们经常这样定义JSON 对象

var jsonObject = {
"username":"admin",
"password":123
}
  • 1
  • 2
  • 3
  • 4

这种形式的我们叫它JSON对象,同时还有一个概念叫做JSON字符串,字符串呢,顾名思义,是由’ ‘或者” “包裹起来的一个整体,我们称之为字符串。我们知道字符串是可以直接输出的,而对象不能直接输出。所以在JavaScript中,我们可以

//定义一个对象 jsonObject
var jsonObject = {
"username":"admin",
"password":123
};
alert(jsonObject);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

此时,会显示[object Object]而不会输出JSON对象的内容,JavaScript向我们提供了两个工具

JSON.parse()
用于将一个 JSON 字符串转换为 JavaScript 对象。
JSON.stringify()
用于将 JavaScript 值转换为 JSON 字符串。

所以当我们输入

alert(JSON.stringify(jsonObject));
  • 1

就会显示 {“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);
}
}
}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

我们首先想想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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

后台成功输出的我们的参数,成功接受!

SpringMVC如此智能,如果我们去除@RequestParam注解,直接将两个值放入会有什么后果?

@RequestMapping("/jsontest")
public void test(String username,String password){
System.out.println("username: " + username);
System.out.println("password: " + password);
}
  • 1
  • 2
  • 3
  • 4
  • 5

竟然同样成功了,原理我这里就不多赘述了,有兴趣的朋友们可以打断点看看。

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);
}
}
}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

后台也更改一下,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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

同时,我又想起了神奇的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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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参数详解的更多相关文章

  1. SpringMVC接受JSON参数详解及常见错误总结我改

    SpringMVC接受JSON参数详解及常见错误总结 最近一段时间不想使用Session了,想感受一下Token这样比较安全,稳健的方式,顺便写一个统一的接口给浏览器还有APP.所以把一个练手项目的前 ...

  2. SpringMVC接受JSON参数详解及常见错误总结

    SpringMVC接受JSON参数详解及常见错误总结 SpringMVC接受JSON参数详解及常见错误总结 最近一段时间不想使用Session了,想感受一下Token这样比较安全,稳健的方式,顺便写一 ...

  3. 谷歌浏览器扩展程序manifest.json参数详解

    { // Required "manifest_version": 2, // manifest编写规范版本,目前主流2 "name": "My Ex ...

  4. springmvc 接受json参数的坑

    构造json数据时候js对象中的值 一定要用 "" 双引号,不能用单引号,因为转成字符串后,到后台进行解析时,因为java认为单引号是单字符 ,转不成对应的字符串,所以会报错! 如 ...

  5. 转:springmvc常用注解标签详解

    Spring5:@Autowired注解.@Resource注解和@Service注解 - IT·达人 - 博客园--这篇顺序渐进,讲得超级好--此人博客很不错http://www.cnblogs.c ...

  6. Spring RestController 请求参数详解

    Spring RestController 请求参数详解 引用作者jpfss 在阅读之前,最好先了解http请求的get,post,以及各种head头类型,请求参数类型. 无参数,设置RestCont ...

  7. $.ajax()方法所有参数详解;$.get(),$.post(),$.getJSON(),$.ajax()详解

    [一]$.ajax()所有参数详解 url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注 ...

  8. 【转】jqGrid 各种参数 详解

      [原文]http://www.cnblogs.com/younggun/archive/2012/08/27/2657922.htmljqGrid 各种参数 详解 JQGrid JQGrid是一个 ...

  9. php setcookie(name, value, expires, path, domain, secure) 参数详解

    setcookie() 定义一个和其余的 HTTP 标头一起发送的 cookie.和其它标头一样,cookie 必须在脚本的任何其它输出之前发送(这是协议限制).这 需要将本函数的调用放到任何输出之前 ...

随机推荐

  1. 电脑c盘爆满检查与设置

    C盘文件爆满,先检查是那个文件造成的 操作方法:打开文件夹选项,将“隐藏受保护的操作系统文件(推荐)”前的勾选去掉,然后打开系统盘查看是那个文件占用空间大 Hiberfil.sys文件删除方法: 1. ...

  2. java——哈希表 HashTable

    在一个类中重写hashCode()和equals() package Date_pacage.hash; public class Student { private int grade; priva ...

  3. docker 安装的centos7.4中无法识别文件中的中文

    在容器内执行命令: 命令: yum -y install kde-l10n-Chinese && yum -y reinstall glibc-common 命令: localedef ...

  4. math.random()方法的使用

    一:导言 以前总是被数字的范围正则搞的头大,在此总结了一下 二:用法 Math.random()函数返回0和1之间的伪随机数,可能为0,但总是小于1,[0,1) 生成n-m,包含n但不包含m的整数: ...

  5. gitee 搭建自己的代码仓库

    git是什么? 还是科普一下吧:Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理(来自我大百度) 现在越来越多的公司已经使用git来进行项目的版本管理,,使用起来 ...

  6. VBS 学习

    VBS其他功能 获取系统用户名 DimWshNetwork Set WshNetwork =CreateObject("WScript.Network") strTaccount ...

  7. HDU - 6208 The Dominator of Strings HDU - 6208 AC自动机 || 后缀自动机

    https://vjudge.net/problem/HDU-6208 首先可以知道最长那个串肯定是答案 然后,相当于用n - 1个模式串去匹配这个主串,看看有多少个能匹配. 普通kmp的话,每次都要 ...

  8. LeetCode 454.四数相加 II(C++)

    给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...

  9. entity framework discriminator error

    前几天使用code first碰到错误:列名 'Discriminator' 无效.这是一个很少见的错误,搜索了很久才发现是code first的poco实体对象的继承问题. 比如,我定义了一个实体类 ...

  10. 基于log4net自定义异步logging组件

    我们在做开发的时候,需要把一些信息记录下来,方便问题排查.数据分析和统计.通常我们使用log4net作为logging的工具,但是大部分时候需要加以封装,以便更加方便的使用,并且不妨碍主业务程序的运行 ...