spring boot 2 全局异常处理

阅读数:100 评论数:0

跳转到新版页面

分类

python/Java

正文

一、spring5之前的springMVC异常处理机制

1、使用@ExceptionHandler

用于局部方法捕获,与抛出异常的方法处于同一个Controller类。

@Controller
public class BuzController {

    @ExceptionHandler({NullPointerException.class})
    public String exception(NullPointerException e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
        return "null pointer exception";
    }

    @RequestMapping("test")
    public void test() {
        throw new NullPointerException("出错了!");
    }
}

2、实现HandlerExceptionResolver接口

定义全局异常。

@Component
public class CustomMvcExceptionHandler implements HandlerExceptionResolver {

    private ObjectMapper objectMapper;

    public CustomMvcExceptionHandler() {
        objectMapper = new ObjectMapper();
    }

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                         Object o, Exception ex) {
        response.setStatus(200);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Cache-Control", "no-cache, must-revalidate");
        Map<String, Object> map = new HashMap<>();
        if (ex instanceof NullPointerException) {
            map.put("code", ResponseCode.NP_EXCEPTION);
        } else if (ex instanceof IndexOutOfBoundsException) {
            map.put("code", ResponseCode.INDEX_OUT_OF_BOUNDS_EXCEPTION);
        } else {
            map.put("code", ResponseCode.CATCH_EXCEPTION);
        }
        try {
            map.put("data", ex.getMessage());
            response.getWriter().write(objectMapper.writeValueAsString(map));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ModelAndView();
    }
}

3、使用@ControllerAdvice

捕获全局异常。@ControllerAdvice 是 Spring MVC 提供的一个注解,它允许你通过类中的方法来全局处理控制器抛出的异常。

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理所有类型的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleAllExceptions(Exception ex, WebRequest request) {
        return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    // 处理特定类型的异常
    @ExceptionHandler(SpecificException.class)
    public ResponseEntity<String> handleSpecificException(SpecificException ex, WebRequest request) {
        return new ResponseEntity<>("A specific error occurred: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

    // 可以添加更多的方法来处理不同类型的异常...
}

@ControllerAdvice 注解可以有选择性地指定它所应用的目标,通过以下属性:

  • basePackages 或 basePackageClasses:指定哪些包中的控制器会被这个 @ControllerAdvice 影响。
  • annotations:指定哪些带有特定注解的控制器会被影响,例如 @RestController
  • assignableTypes:指定哪些具体的控制器类会被这个 @ControllerAdvice 影响。

默认情况下,如果不设置这些属性,@ControllerAdvice 会应用于所有的控制器。

此外,@ControllerAdvice 可以与 @ResponseBody 结合使用,这样异常处理方法就可以直接返回响应体:

二、Spring 5 WebFlux异常处理

webflux支持mvc注解。

1、webFlux定义对request的处理方式

(1)定义处理逻辑 HandlerFunction

HandlerFunction相当于Controller中的具体处理方法。

@Component
public class TimeHandler {
    public Mono<ServerResponse> getTime(ServerRequest serverRequest) {
        String timeType = serverRequest.queryParam("type").get();
        //return ...
    }
}

(2)配置对什么样的url来进行响应 RouterFunction

相当于@RequestMapping

@Configuration
public class RouterConfig {
    private final TimeHandler timeHandler;

    @Autowired
    public RouterConfig(TimeHandler timeHandler) {
        this.timeHandler = timeHandler;
    }

    @Bean
    public RouterFunction<ServerResponse> timerRouter() {
        return route(GET("/time"), req -> timeHandler.getTime(req));
    }
}

2、功能级处理异常 onErrorResume

@Component
public class TimeHandler {
    public Mono<ServerResponse> getTime(ServerRequest serverRequest) {
        String timeType = serverRequest.queryParam("time").orElse("Now");
        return getTimeByType(timeType).flatMap(s -> ServerResponse.ok()
                .contentType(MediaType.TEXT_PLAIN).syncBody(s))
                .onErrorResume(e -> Mono.just("Error: " + e.getMessage()).flatMap(s -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).syncBody(s)));
    }

    private Mono<String> getTimeByType(String timeType) {
        String type = Optional.ofNullable(timeType).orElse(
                "Now"
        );
        switch (type) {
            case "Now":
                return Mono.just("Now is " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
            case "Today":
                return Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            default:
                return Mono.empty();
        }
    }
}

3、全局异常处理 ErrorWebExceptionHandler

 

 




相关推荐

方式一:@ExceptionHandler 在一个controller内的统一处理 import or

一、概述 RequestBodyAdvice 和 ResponseBodyAdvice来对请求前后进行处理,本质上他俩都是AOP拦截器。  RequestBodyAdvice 和 ResponseBo