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

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数据的方法:

既然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",

【不写就是用的默认的jQuery默认使用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的类型,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对象

 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<String,Object> 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281402.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件定义存储的定制化怎么走?

引言 当前&#xff0c;软件定义存储成为业内超高速增长的典型。有研究人员称&#xff0c;从2014年到2019年&#xff0c;软件定义存储市场将从14亿美元增长到62亿美元以上&#xff0c;年复合增长率将达35%。软件定义存储所带来的优势显而易见&#xff0c;但是对于企业来说&#…

Golang并发模型:合理退出并发协程

goroutine作为Golang并发的核心&#xff0c;我们不仅要关注它们的创建和管理&#xff0c;当然还要关注如何合理的退出这些协程&#xff0c;不&#xff08;合理&#xff09;退出不然可能会造成阻塞、panic、程序行为异常、数据结果不正确等问题。这篇文章介绍&#xff0c;如何合…

剑网服务器维护,12月31日服务器例行维护公告

隐元秘鉴新增以下江湖行里使用趣味道具的成就&#xff1a;压酒唤客尝&#xff1a;使用压酒三十次欲解红烛意&#xff1a;使用烛影三十次闲情吹笛子&#xff1a;使用吹断三十次引弦中落雀&#xff1a;使用千鸟三十次黄云动风色&#xff1a;使用风色三十次卷抒平生意&#xff1a;…

一款 Windows 软件快捷助手

WPF 开发的 Windows 软件快捷助手Windows 软件快捷助手作者&#xff1a;WPFDevelopersOrg - 驚鏵原文链接&#xff1a;https://github.com/WPFDevelopersOrg/SoftwareHelper框架使用.NET40&#xff1b;Visual Studio 2019;项目使用 MIT 开源许可协议&#xff1b;项目使用 MVV…

关于8位AD_DA转换芯片的采样率问题

关于使用Keil计算程序执行时间 打开Keil程序&#xff0c;进入“启动/停止调试”界面。在需要暂停的地方设置断点&#xff08;在该句程序前双击&#xff09;。在程序上方有一行工具栏&#xff1a;此工具栏分别代表复位、运行、停止、步进、步越、步出、运行到光标处等。 点击运…

CYQ.Data 数据框架 V4.0 开源版本发布(源码提供下载,秋色园V2.5版本标配框架)

说明的说明&#xff1a; 博客园团队两次移此文出首页&#xff0c;说 这篇文章不属于知识分享型文章&#xff0c;并且有广告嫌疑。 本文的确属于分享型文章&#xff0c;而且分享的知识点比其它文章都多很多&#xff0c;看看网友回复“谢谢分享”就知道是分享型文章了。 所谓广告…

oracle 分组后取每组第一条数据

数据格式 分组取第一条的效果 sql SELECT * FROM (SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC) rn, test1.* FROM test1) WHERE rn 1 ;

永大服务器进去显示字母,永大电梯服务器使用说明

永大电梯服务器使用说明2021-05-25一&#xff0e; 目的&#xff1a;用于工务交车前对MPU和XDR板进行调试。二&#xff0e; 对应作业&#xff1a;1-1对MPU电梯调试接线连接&#xff1a;1).对MPUGB2(A2)版电梯调试时(以及A2前版本)&#xff0c;接线情况如下&#xff1a;连接顺序连…

树莓派Zero 2 W(ubuntu-22.04)通过.NET6和libusb操作USB读写

有这个想法的初衷喜欢电子和DIY硬件的朋友对稚晖君应该都不陌生&#xff0c;他定期都会分享一些自己做的好玩的硬件&#xff0c;他之前做了一个ElectronBot桌面机器人我就很感兴趣&#xff0c;所以就自己也做了一个。起初我只是自己开发了一个叫电子脑壳的上位机软件&#xff0…

bzoj4589

fwt 原理并不知道 nim游戏石子异或和0后手赢 那么也就是求a[1]^a[2]^...^a[n]0的方案数 这个和bzoj3992一样可以dp dp[i][j]表示前i个数异或和为j的方案数 dp[0][0] 1 dp[i][j] dp[i - 1][k] * a[p] p ^ k j a[p] 0 / 1 表示有没有p这个数 这个东西也不能矩阵快速幂 但是我…

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 85

UnicodeDecodeError: ascii codec cant decode byte 0xe5 in position 85;import sys reload(sys) sys.setdefaultencoding(utf8)

JS设计模式五:职责链模式

职责链模式简述 职责连是由多个不同的对象组成的&#xff0c;有发送者跟接收者&#xff0c;分别负责信息的发送跟接收&#xff0c;其中&#xff0c;链中第一个对象是 职责连是由多个不同的对象组成的&#xff0c;发送者是发送请求的对象&#xff0c;接收者接收请求并且对其进行…

web框架之Django(一)

Python的WEB框架有Django、Tornado、Flask 等多种&#xff0c;Django相较与其他WEB框架其优势为&#xff1a;大而全&#xff0c;框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。 基本配置 一、创建django程序 终端命令&#xff1a;django-admin startprojec…

写一个易于维护使用方便性能可靠的Hybrid框架(一)—— 思路构建

写一个易于维护使用方便性能可靠的Hybrid框架&#xff08;二&#xff09;—— 插件化 写一个易于维护使用方便性能可靠的Hybrid框架&#xff08;三&#xff09;—— 配置插件 前言 本来上一篇博文写完&#xff0c;我就告诉自己&#xff0c;这是最后一篇&#xff0c;之后不再总结…

程序员制作出价值5亿外卖神器却不能取消订单,你知道吗?

小编今日给大家带来RACDisopsable&#xff0c;大家可能有部分人对这个会感觉到很陌生&#xff0c;那么我就用一句话来表达就是他可以帮我们取消订阅。那么又会有人会对这个产生疑问了&#xff0c;我们什么时候需要用到这个取消订阅了打个实际的例子来说吧&#xff0c;今天我在饿…

Computer

链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2196https://blog.csdn.net/shuangde800/article/details/9732825#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<cmath&…

智慧“昆明”在路上 未来充满精彩

智慧城市是运用物联网、云计算、大数据、移动互联网、空间地理信息集成等新一代信息技术&#xff0c;促进城市规划、建设、管理和服务智慧化的新理念和新模式。近年来&#xff0c;昆明市全面加快智慧城市建设&#xff0c;力争通过三年的努力&#xff0c;打造区域信息辐射中心的…

《精读 Mastering ABP Framework》教程发布

精读《Mastering ABP Framework》学习总结&#xff0c;掌握软件开发最佳实践&#xff0c;构建可维护 .NET 解决方案。从 ABP Framework 框架中学习如何构建现代 WEB 应用程序。掌握 ABP Framework 框架ABP Framework 是一个完整的基础架构&#xff0c;遵循软件开发最佳实践&…

C# 委托知识总结

1.什么是委托&#xff0c;为什么要使用委托 我正在埋头苦写程序&#xff0c;突然想喝水&#xff0c;但是又不想自己去掉杯水而打断自己的思路&#xff0c;于是我就想让女朋友去给我倒水。她去给我倒水&#xff0c;首先我得让她知道我想让她干什么&#xff0c;通知她之后我可以继…

阿里云大学课程学习有奖征文活动现在开始

2019独角兽企业重金招聘Python工程师标准>>> "学有所获&#xff0c;分享为美"--阿里云大学课程学习有奖征文活动开始啦~~ 看课程&#xff0c;写心得&#xff0c;赢千元大奖&#xff0c;还有机会加入阿里云大学技术作者群&#xff01;想试试自己的技术文笔…