Spring-@ControllerAdvice-全局处理注解

1,@ControllerAdvice 介绍

@ControllerAdvice 是 Spring 框架提供的一个注解,用于定义全局的异常处理器和全局数据绑定。它通常用于集中处理应用程序中的异常,并提供统一的异常处理逻辑。

2,@ControllerAdvice 的基本使用

package org.springframework.web.bind.annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {

    //指定包
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};
    
    //指定类
    Class<?>[] basePackageClasses() default {};

    Class<?>[] assignableTypes() default {};
    
    //指定注解
    Class<? extends Annotation>[] annotations() default {};
}

1. @ControllerAdvice 注解是一个带有 @Component 注解的特殊注解,它会被 Spring 框架扫描并识别为全局异常处理器。

2. 一旦 Spring 框架发现了带有 @ControllerAdvice 注解的类,它就会将其实例化为一个 Bean,并将其注册到应用程序上下文中。

3. @ControllerAdvice注解可以通过结合其他注解来定义不同类型的全局处理器,包括:

  • @ExceptionHandler:用于定义特定类型的异常处理方法,当Controller层抛出异常时,Spring框架会根据异常类型选择合适的@ExceptionHandler方法进行处理,并返回相应的结果或视图。
  • @InitBinder:用于定制数据绑定的方法, 同样地,@InitBinder注解定义的方法会在数据绑定过程中被调用,用于定制数据绑定的逻辑。
  • @ModelAttribute:用于提供全局数据的方法,@ModelAttribute注解定义的方法会在每个请求处理方法执行之前被调用,用于提供全局的数据模型。

3,使用示例

1,@ExceptionHandler

自定义异常处理

  1. 自定义一个异常
public class CustomException extends RuntimeException{}
  1. 自定义异常处理器
package com.apz.demo.handler;

import com.apz.demo.exception.CustomException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author gx
 * @date 20221130
 * 自定义异常处理
 * ControllerAdvice 配合 ExceptionHandler 拦截 controller 的异常
 *
 * ResponseEntity 可以修改返回的 http 状态码
 */
@ControllerAdvice(basePackages = "com.apz.demo.controller")
public class CustomerExceptionHandler {
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseEntity error(CustomException e){
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.parser());
    }
}

这里 error 方法,可以自定义返回数据,如果是 Json,就需要加上 ResponseBody。如果是重定向路径,就返回 ModelAndView 对象。

  1. 程序中抛出这个对应的异常
@RequestMapping("/demo1")
public String test() throws CustomException{
    throw CustomException.paramNullException("测试");
}    

当程序抛出异常时候,就会走自定义处理异常,返回数据到前端。

2,@ModelAttribute

全局参数绑定

  1. 自定义一个全局参数绑定
//第一种方式:这种方式直接放到 model 里
@ModelAttribute
public void modeAttrParam(Model model){
    model.addAttribute("l1", "yq");
    model.addAttribute("l2", "xx");
    model.addAttribute("l3", "yl");
}

//第二种方式:如果设置了 ss,就是把 key = ss,value 是整个 map 放到 model里,如果不设置 ss, 返回的变量名就是放到 model 里的 key。
@ModelAttribute("ss")
public Map<String, String> modeAttrParam1(){
    Map<String, String> map = new HashMap<>();
    map.put("key1", "value1");
    map.put("key2", "value2");
    map.put("key3", "value3");
    return map;
}
  1. 三种方式获取全局参数设置的值

@RequestMapping("/demo2")
public void test1(Model model){
    Map<String, Object> stringObjectMap = model.asMap();
    System.out.println(stringObjectMap);
}

@RequestMapping("/demo3")
public void test2(@ModelAttribute("l3") String globalAttr){
    System.out.println(globalAttr);
}

@RequestMapping("/demo4")
public void methodThree(ModelMap modelMap) {
    System.out.println(modelMap);
}

3,@InitBinder

参数绑定

  1. 定义参数绑定
@InitBinder
public void dateTypeBinder(WebDataBinder webDataBinder){
    //往数据绑定器中添加一个DateFormatter日期转化器。
    webDataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
}
  1. 接口参数会自动解析
@RequestMapping("/testInitBinder")
private String testInitBinder(Date date){
    System.out.println("date = " + date);
    return "RequsetInitBindDemo";
}
posted @ 2024-03-07 16:15  primaryC  阅读(81)  评论(0编辑  收藏  举报