PHP笔记网

革命尚未成功,同志仍须努力下载JDK17

作者:Albert.Wen  添加时间:2022-08-11 15:24:39  修改时间:2024-12-18 19:29:49  分类:06.Java框架/系统  编辑

我们知道无论是 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 上需要接收两个实体类的数据,接收方法可以这么定义:

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

(3)但由于两个实体类中都有 name 属性,那么参数传递时就会发生混淆。

2、解决办法

(1)使用 @ControllerAdvice 结合 @InitBinder 即可解决上面的问题,这里我们创建一个全局的参数预处理配置。

代码说明:

  • 第一个 @InitBinder("user") 表示该方法是处理 Controller 中 @ModelAttribute("user") 对应的参数。
  • 第二个 @InitBinder("book") 表示该方法是处理 Controller 中 @ModelAttribute("book") 对应的参数。
  • 这两个方法中给相应的 Filed 设置一个前缀。

补充说明:在 WebDataBinder 对象中,除了可以设置前缀,还可以设置允许、禁止的字段、必填字段以及验证器等等。

package com.example.demo;
 
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 注解:

package com.example.demo;
 
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("/hello")
    public String hello(@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 来单独定义预处理方法,具体参考我写的另一篇文章:

 

 

 

摘自:https://www.hangge.com/blog/cache/detail_2483.html