SpringBoot實現前后端數據交互、json數據交互、Controller接收參數的幾種常用方式


https://blog.csdn.net/qq_20957669/article/details/89227840

現在大多數互聯網項目都是采用前后端分離的方式開發,前端人員負責頁面展示和數據獲取,后端負責業務邏輯處理和接口封裝。當與前端交互的過程當中,常用json數據與前端進行交互,這樣想取出前端傳送過來的json數據的時候,就需要用到@RequestBody這個注解。@RequestBody注解用於讀取http請求的內容(字符串),通過springmvc提供的HttpMessageConverter接口將讀到的內容轉換為json、xml等格式的數據並綁定到controller方法的參數上。 

提交方式為 POST 時,

JQuery Ajax 以 application/x-www-form-urlencoded 上傳 JSON對象 ,

后端用 @RequestParam 或者Servlet 獲取參數。

JQuery Ajax 以 application/json 上傳 JSON字符串,

后端用 @RquestBody 獲取參數。

獲取參數的幾種常用注解

@PathVariable:一般我們使用URI template樣式映射使用,即url/{param}這種形式,也就是一般我們使用的GET,DELETE,PUT方法會使用到的,我們可以獲取URL后所跟的參數。

@RequestParam:一般我們使用該注解來獲取多個參數,在()內寫入需要獲取參數的參數名即可,一般在PUT,POST中比較常用。

@RequestBody:該注解和@RequestParam殊途同歸,我們使用該注解將所有參數轉換,在代碼部分在一個個取出來,也是目前我使用到最多的注解來獲取參數
 

還有@RequestHeader來獲取頭信息里的值,@CookieValue來獲取Cookie值等等。在這,我也僅僅說明一些較常用的取值方法而已。

一.請求路徑參數

get請求

一般用於查詢數據,采用明文進行傳輸,一般用來獲取一些無關用戶信息的數據,

@GetMapping 組合注解,是 @RequestMapping(method = RequestMethod.GET) 的縮寫

1.get請求,url路徑傳參

get請求一般通過url傳參,如:
http://localhost:4001/api/unit?code=111
后端要獲取code參數,可以使用@RequestParam注解


   
   
  
  
          
  1. @RestController
  2. public class HelloController {
  3. @RequestMapping(value="/hello",method= RequestMethod.GET)
  4. public String sayHello(@RequestParam Integer id){
  5. return "id:"+id;
  6. }
  7. }

2.get請求,url路徑參數

如:http://localhost:4001/api/unit/1
后端使用@PathVariable可以接收路徑參數1。


   
   
  
  
          
  1. @RestController
  2. public class HelloController {
  3. @RequestMapping(value="/hello/{id}/{name}",method= RequestMethod.GET)
  4. public String sayHello(@PathVariable("id") Integer id,@PathVariable("name") String name){
  5. return "id:"+id+ " name:"+name;
  6. }
  7. }

小結:當請求為get請求時,使用@PathVariable或者@RequestParam獲取參數值,獲取路徑參數。@PathVariable一般用於獲取獲取url/{id}這種形式的參數;@RequestParam獲取查詢參數。即url?name=這種形式

二、Body參數

POST請求

1、post請求,Body傳值
較推薦使用json格式傳值,postman設置如圖:

后端接受這種數據應該采用@RequestBody或者@requestparam


   
   
  
  
          
  1. //map接收
  2. @PostMapping(path = "/demo1")
  3. public void demo1(@RequestBody Map<String, String> person) {
  4. System.out.println(person.get( "name"));
  5. }
  6. //或者是實體對象接收
  7. @PostMapping(path = "/demo1")
  8. public void demo1(@RequestBody Person person) {
  9. System.out.println(person.toString());
  10. }

 注意;@RequestBody,它是用來處理前台定義發來的數據Content-Type: 而不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等;使用@RequestBody注解接收參數的時候,從名稱上來看也就是說要讀取的數據在請求體里,前台的Content-Type必須要改為application/json,所以要發post請求,因為Ajax使用的POST,並且發送的是JSON對象。前端必須指定請求json數據的contentType為:application/json,否則會報類型不支持的異常錯誤“org.springframework.web.HttpMediaTypeNotSupportedException”

當Ajax以application/x-www-form-urlencoded格式上傳即使用JSON對象,后台只能使用@RequestParam 或者Servlet獲取參數。 當Ajax以application/json格式上傳即使用JSON字符串,后台可以使用@RquestBody或者@RequestParam獲取。


如何定義后台接收參數“能映射上去”呢?若是json中的key在實體中都能找到對應的field,自動映射,也就是說:前台傳入的json中的key在實體中必須要存在,不然就會報錯 

第三類:請求頭參數以及Cookie

post請求,Headers、cookie傳值

 

在這里我們把Content-Type設置為了json格式。
我們還可以在headers里面加入別的參數,比如Token。
后端可以通過HttpServletRequest 獲取請求頭的內容,如:


   
   
  
  
          
  1. request.getHeader(string name)方法:String
  2. request.getHeaders(String name)方法:Enumeration
  3. request.getHeaderNames()方法
  4. @GetMapping("/demo3")
  5. public void demo3(HttpServletRequest request) {
  6. System.out.println(request.getHeader( "myHeader"));
  7. for (Cookie cookie : request.getCookies()) {
  8. if ( "myCookie".equals(cookie.getName())) {
  9. System.out.println(cookie.getValue());
  10. }
  11. }
  12. }

四、HttpServletRequest 

前端js發送ajax請求,Content-Type發送信息至服務器時內容編碼類型,默認是( application/x-www-form-urlencoded 這種格式的特點就是,name/value 成為一組,每組之間用 & 聯接,這種形式是沒有辦法將復雜的 JSON 組織成鍵值對形式),

data_type設置你收到服務器數據的格式,不指定自動判斷


   
   
  
  
          
  1.   var jsonObj = { "openid": "xxx", "username": "Ed sheeran", "password": "123"};
  2.           /*
  3.               Jquery默認Content-Type為application/x-www-form-urlencoded類型
  4.            */
  5.           $.ajax({
  6.               type: 'POST',
  7.               url: "/login",
  8.               dataType: "json",
  9.               data: JSON.stringify(jsonObj),
  10.               success: function(data) {
  11.                   console.log(data)
  12.               },
  13.               error: function() {
  14.                   console.log( "fucking error")
  15.               }
  16.           });


​后端Servlet接受參數。前端報 200,后端報 返回值都是null


   
   
  
  
          
  1. @Controller
  2. public class LoginController {
  3.   @PostMapping("/login")
  4.   public void login(HttpServletRequest request){
  5.       System.err.println(request.getParameter( "openid"));
  6.       System.err.println(request.getParameter( "username"));
  7.       System.err.println(request.getParameter( "password"));
  8. }



后端改 @RequestBody 接受參數。前端報 415,后端報 Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported

Http status 415 Unsupported Media Type


   
   
  
  
          
  1. @Controller
  2. public class LoginController {
  3.   @PostMapping("/login")
  4.   public void login(@RequestBody Map<String,Object> map){
  5.       System.err.println(map.get( "username"));
  6.       System.err.println(map.get( "password"));
  7.       System.err.println(map.get( "openid"));
  8.   }


前端加 contentType : “application/json”。前端報 200,后端能接受到參數

   


   
   
  
  
          
  1. var jsonObj = { "openid": "xxx", "username": "Ed sheeran", "password": "123"};
  2. $.ajax({
  3.               type: 'POST',
  4.               url: "/login",
  5.               dataType: "json",
  6.               data: JSON.stringify(jsonObj),
  7.               contentType : "application/json",
  8.               success: function(data) {
  9.                   console.log(data)
  10.               },
  11.               error: function() {
  12.                   console.log( "fucking error")
  13.               }
  14.           });

   
   
  
  
          
  1. @Controller
  2. public class LoginController {
  3.   @PostMapping("/login")
  4.   public void login(@RequestBody Map<String,Object> map){
  5.       System.err.println(map.get( "username"));
  6.       System.err.println(map.get( "password"));
  7.       System.err.println(map.get( "openid"));
  8. }
  9. }


后端使用對象來獲取參數。前端報 200,后端 也ok@Controller


   
   
  
  
          
  1. public class LoginController {
  2.   @PostMapping("/login")
  3.   public void login(@RequestBody Form form){
  4.       System.err.println(form);
  5. }
  6. }


 


   
   
  
  
          
  1. public class Form {
  2.   private String openid;
  3.   private String username;
  4.   private String password;
  5.   // get set
  6.   @Override
  7.   public String toString() {
  8.       return "Form{" +
  9.               "openid='" + openid + '\'' +
  10.               ", username='" + username + '\'' +
  11.               ", password='" + password + '\'' +
  12.               '}';
  13.   }
  14. }

四、參數校檢

 

1.后端接收到前端的數據,如果想對前端的數據進行校驗,可以加入springboot的Validate 功能依賴包


   
   
  
  
          
  1. <dependency>
  2. <groupId>org.hibernate </groupId>
  3. <artifactId>hibernate-validator </artifactId>
  4. </dependency>

 使用只需要在接收數據的實體上加上@Valid注解,BindingResult接收錯誤的不合法的提示信息

接收參數的實體的屬性上還需要加校驗的注解@NotEmpty(message="密碼不能為空")


   
   
  
  
          
  1. 還可以使用正則表達式對屬性進行校驗。只需要加入以下注解即可:
  2. @Pattern(
  3. regexp = 正則表達式,
  4. message = "輸入格式不合法"
  5. )

2、當后端接收完前端的數據,響應一般也是返回json數據給前端,此時只需要在后端控制器Contoller類加上@ResponseBody即可。該注解用於將Controller的方法返回的對象,通過HttpMessageConverter接口轉換為指定格式的數據如:json,xml等,通過Response響應給客戶端。@Controller 與 @ResponseBody 結合使用返回json數據給前端,我們還可以使用@RestController替換他們,從而使代碼更加的精簡

注意: 
接收到的參數默認都是字符串類型的 
有的注解只能用在String類型的屬性上

@JsonProperty可以實現前端的屬性名和后台實體類的屬性名不一致問題

校驗方式: 
使用@RequestBody @Valid 對JSON參數進行獲取和校驗

 


最終選擇交互方式

前端 application/json,post請求,上傳 josn字符串, 后端結合@RequestBody 使用自定義對象 或者 Map接收參數,這是最常用的方法

前端代碼


   
   
  
  
          
  1.     var jsonObj = { "openid": "xxx", "username": "Ed sheeran", "password": "123"};
  2.           /*
  3.               Jquery默認Content-Type為application/x-www-form-urlencoded類型
  4.            */
  5.           $.ajax({
  6.               type: 'POST',
  7.               url: "/login",
  8.               dataType: "json",
  9.               data: JSON.stringify(jsonObj),
  10.               contentType : "application/json",
  11.               success: function(data) {
  12.                   console.log(data)
  13.               },
  14.               error: function() {
  15.                   console.log( "fucking error")
  16.               }
  17.           });


后端代碼1


   
   
  
  
          
  1. @Controller
  2. public class LoginController {
  3.   @PostMapping("/login")
  4.   public void login(@RequestBody Form form){
  5.       System.err.println(form);
  6. }
  7. }

后端代碼2


   
   
  
  
          
  1. @Controller
  2. public class LoginController {
  3.   @PostMapping("/login")
  4.   public void login(@RequestBody Map<String,Object> map){
  5.       System.err.println(map.get( "username"));
  6.       System.err.println(map.get( "password"));
  7.       System.err.println(map.get( "openid"));
  8. }
  9. }

如果是get請求,結合 @RequestParam 或者@PathVariable獲取路徑參數

如果是通過header傳值,使用HttpServletRequest獲取

如果是post請求body傳參,對於參數較多的,可以使用對象或者map結合@RequestBody使用接收參數,如果是少量參數,可以使用@RequestParam單個映射接收。

參考文獻

SpringBoot 前后端json數據交互

原生Ajax與JQuery Ajax

SpringMVC接受JSON參數詳解及常見錯誤總結

Controller接收參數以及參數校驗

AJAX POST請求中參數以form data和request payload形式在servlet中的獲取方式

SpringBoot實戰 之 數據交互篇

SpringBoot Controller接收參數的幾種常用方式

spring boot常見get 、post請求參數處理、參數注解校驗、參數自定義注解校驗


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM