博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC接受JSON参数详解及常见错误总结我改
阅读量:5320 次
发布时间:2019-06-14

本文共 6218 字,大约阅读时间需要 20 分钟。

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

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

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

var jsonObject = {"username":"admin","password":123}

 

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

//定义一个对象 jsonObjectvar 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数据的方法:

既然JSON有着上述两种存在方式,那我们通过ajax向SpringMVC传值的时候,我们该传哪一种呢? 

我们首先尝试直接发送JSON对象

1 //定义json对象 2             var username = $("#username").val(); 3             var password = $("#password").val(); 4             var json = { 5                 "username" : username, 6                 "password" : password 7             }; 8  9 // Jquery Ajax请求10 $.ajax({11                 url : "jsontest",12                 type : "POST",13                 async : true,14                 data : json,15                 dataType : 'json',16                 success : function(data) {17                     if (data.userstatus === "success") {18                         $("#errorMsg").remove();19                     } else {20                         if ($("#errorMsg").length <= 0) {21                             $("form[name=loginForm]").append(errorMsg);22                         }23                     }24                 }25             });

 

我们首先想想SpringMVC提供了什么给我们,有一个@RequestParam的注解,对于这个注解,它的作用和我们Servlet中的request.getParameter是基本相同的。我们首先使用这个注解来获取

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

 

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

 

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

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

 

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

 

上面是第一种传json格式数据到后台的方法,关键就是两点

1、前台传的是json对象。(我觉得传json字符串也可以,还没有测试过)

同时,ajax中绝对不能写 contentType : "application/json",

【不写就是用的默认的默认使用application/x-www-form-urlencoded类型】

2、在java的controller中可以用这个@RequestParam

 也可以什么都不写,直接用字符串参数接收但是绝对不能写@RequestBody

 

 

————————————————————————————————————————————————

 

第二种传json数据到后台的方法:

SpringMVC提供了一个@RequestBody,它是用来处理前台定义发来的数据Content-Type: 不是application/x-www-form-urlencoded编码的内容,

例如application/json, application/xml等; 

细心的朋友们或许发现了,在之前的Ajax中,我们没有定义Content-type的类型,默认使用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对象

1 $.ajax({ 2                 url : "jsontest", 3                 type : "POST", 4                 async : true, 5                 contentType : "application/json", 6                 data : JSON.stringify(json), 7                 dataType : 'json', 8                 success : function(data) { 9                     if (data.userstatus === "success") {10                         $("#errorMsg").remove();11                     } else {12                         if ($("#errorMsg").length <= 0) {13                             $("form[name=loginForm]").append(errorMsg);14                         }15                     }16                 }17             });

 

后台也更改一下,json其实可以理解为键值对嘛,所以我们用Map接收,然后对字符串或者其他数据类型进行进一步处理。

1     @RequestMapping("/jsontest")2     public void test(@RequestBody(required=true) Map
map ){3 String username = map.get("username").toString();4 String password = map.get("password").toString();5 System.out.println("username: " + username);6 System.out.println("password: " + password);7 }

 【数据少可以用map接收也可以在原有的实体类中加入临时的(只为接收传递参数而不用来操作数据库的)成员变量来接收】

 

同时,我又想起了神奇的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数据到后台的方法,关键总结就两点

1、我们后台使用@RequestBody注解的时候,

前台的ajax发送请求时,必须加上contentType : "application/json",

而且发送的必须是json字符串 JSON.stringify(json) 绝对不能是json对象{}
 

2、此时后台controller中必须用@RequestBody注解

 

3、补充第3点要注意的地方:

如果后台用@RequestBody注解,这样就要求前台ajax必须用 

contentType : "application/json"

方式,当同一次请求除了传递json类型还传递许多其他的类型参数比如字符串参数时,就或报400错误。这个是个硬伤,要用这种方式,Controller层方法中只能接收一个Json类型的参数,不能再有其他类型的参数。

  • 我们首先说了JSON对象和JSON字符串
  • 然后说了SpringMVC接受两种两种JSON格式的时候,前端ContentType的设定,和后端是否使用注解接受,还提到了一点Servlet。 

 

  • 当Ajax以application/x-www-form-urlencoded格式上传即使用JSON对象,后台需要使用@RequestParam 或者Servlet获取。 当Ajax以application/json格式上传即使用JSON字符串,后台需要使用@RquestBody获取。
这是我实验了一天的一些总结,希望可以帮助到大家,如果有错误,请各位海涵并指正。

转载于:https://www.cnblogs.com/libin6505/p/6812791.html

你可能感兴趣的文章
ORA-01502: 索引'P_ABCD.PK_WEB_BASE'或这类索引的分区处于不可用状态
查看>>
Java抽象类和接口的比较
查看>>
MyBaits学习
查看>>
管道,数据共享,进程池
查看>>
CSS
查看>>
[Cypress] Stub a Post Request for Successful Form Submission with Cypress
查看>>
SDUTOJ3754_黑白棋(纯模拟)
查看>>
如何改善下面的代码 领导说了很耗资源
查看>>
php中的isset和empty的用法区别
查看>>
Android ViewPager 动画效果
查看>>
把word文档中的所有图片导出
查看>>
浏览器的判断;
查看>>
ubuntu 18.04取消自动锁屏以及设置键盘快捷锁屏
查看>>
Leetcode 589. N-ary Tree Preorder Traversal
查看>>
机器学习/深度学习/其他开发环境搭建记录
查看>>
xml.exist() 实例演示
查看>>
判断是否为空然后赋值
查看>>
zabbix监控日志文件
查看>>
正则表达式
查看>>
pip install torch on windows, and the 'from torch._C import * ImportError: DLL load failed:' s...
查看>>