1. 程式人生 > 其它 >SpringBoot - @ControllerAdvice的使用詳解3(請求引數預處理 @InitBinder)

SpringBoot - @ControllerAdvice的使用詳解3(請求引數預處理 @InitBinder)

我們知道無論是Get請求還是Post請求,Controller這邊都可以定義一個實體類來接收這些引數。而@ControllerAdvice結合@InitBinder還能實現請求引數預處理,即將表單中的資料繫結到實體類上時進行一些額外處理。

三、請求引數預處理(搭配 @InitBinder)

1,問題描述

(1)假設我們有如下兩個實體類User和Book:
public class User {
    private String name;
    private Integer age;
   // 省略getter/setter
}
 
public class Book {
    
private String name; private Float price; // 省略getter/setter }

(2)如果在Contoller上需要接收兩個實體類的資料,接收方法可以這麼定義:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @GetMapping("/hello2")
    
public String hello2(User user, Book book) { return "name:" + user.getName() + " | age:" + user.getAge() + "<br>" + "name:" + book.getName() + " | price:" + book.getPrice(); } }

2,解決辦法

(1)使用@ControllerAdvice結合@InitBinder即可解決上面的問題,這裡我們建立一個全域性的引數預處理配置。
程式碼說明:
第一個 @InitBinder(
"user") 表示該方法是處理 Controller 中 @ModelAttribute("user") 對應的引數。 第二個 @InitBinder("book") 表示該方法是處理 Controller 中 @ModelAttribute("book") 對應的引數。 這兩個方法中給相應的 Filed 設定一個字首。 補充說明:在 WebDataBinder 物件中,除了可以設定字首,還可以設定允許、禁止的欄位、必填欄位以及驗證器等等。
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
 
@ControllerAdvice
public class GlobalConfig {
    @InitBinder("user")
    public void init1(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("user.");
    }
    @InitBinder("book")
    public void init2(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("book.");
    }
}

(2)然後Controller中方法的引數新增@ModelAttribute註解:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @GetMapping("/hello3")
    public String hello3(@ModelAttribute("user") User user,
                        @ModelAttribute("book") Book book) {
        return "name:" + user.getName() + " | age:" + user.getAge() + "<br>"
                + "name:" + book.getName() + " | price:" + book.getPrice();
    }
}

(3)最後瀏覽器請求引數中新增相應的字首,即可成功區分出name屬性:

當然也可以在Cotroller裡面使用@InitBinder來單獨定義預處理方法,具體參考我寫的另一篇文章:

SpringBoot - 獲取Get請求引數詳解(附樣例:非空、預設值、陣列、物件)

早年同窗始相知,三載瞬逝情卻萌。年少不知愁滋味,猶讀紅豆生南國。別離方知相思苦,心田紅豆根以生。