SpringBoot 使用@ControllerAdvice2:@ModelAttribute、@InitBinder使用

原创
2021/04/20 22:26
阅读数 910

@ControllerAdvice 是一种作用于控制层的切面通知(Advice),该注解能够将通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法收集到一个类型,并应用到所有控制器上。

 

@ModelAttribute 添加全局数据

一、设置全局数据

先准备一个实体类对象。

public class User {

    private String username;

    private Integer age;
}

编写设置全局数据配置。 

import com.example.demo.model.Demo;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

/**
 * @author piao
 * @date 2021-04-20
 */
@ControllerAdvice
public class DemoConfig {

    /************************************  方法一 ***************************************/

    @ModelAttribute(value = "demo")
    public String demoStr() {
        return "this is demo";
    }

    @ModelAttribute(value = "demo")
    public Demo demoObj() {
        return new Demo().setUsername("piao").setPassword("123");
    }

    /************************************  方法二 ***************************************/

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("msg", "this is demo");

        Demo demo = new Demo().setUsername("piao").setPassword("123");
        model.addAttribute("demo", demo);
    }

}

 

二、获取全局数据 

@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping("/1")
    public String hello(@ModelAttribute("msg") String msg, @ModelAttribute("demo") Demo demo) {
        return "msg:" + msg + "<br/>" + "demo:" + demo;
    }

    @GetMapping("/2")
    public String hello(Model model) {
        Map<String, Object> map = model.asMap();
        String msg = map.get("msg").toString();
        Demo demo = (Demo) map.get("demo");

        return "msg:" + msg + "<br/>" + "demo:" + demo;
    }

}

 

三、验证结果

 

@InitBinder 请求参数预处理

结合 @InitBinder 还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。

一、请求问题

1、编写两个实体类,用来接收参数

@Data
@Accessors(chain = true)
public class Demo {

    private String username;

    private String password;

}

@Data
@Accessors(chain = true)
public class User {

    private String username;

    private Integer age;
}

2、编写 Controller 请求接口

@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping()
    public String demo(Demo demo, User user) {
        return "demo username:" + demo.getUsername() + " | user username:" + user.getUsername();
    }
}

3、请求测试,抛出问题

我们传递了两个username值,希望被demo和user对象分别接收,最终却被两个对象一起接收并拼接了。

 

二、编写解放方法

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

@ControllerAdvice
public class DemoConfig {

    @InitBinder("user")
    public void init1(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("user.");
    }

    @InitBinder("demo")
    public void init2(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("demo.");
    }

}

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

2、编写 Controller 代码

@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping()
    public String demo(@ModelAttribute("demo") Demo demo, @ModelAttribute("user") User user) {
        return "demo username:" + demo.getUsername() + " <br/> user username:" + user.getUsername();
    }

}

 

三、验证结果

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部