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.pswp.cn/news/281402.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281402.shtml
英文地址,請注明出處:http://en.pswp.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;想試試自己的技術文筆…