zoukankan      html  css  js  c++  java
  • 全局异常

    我们知道在web开发中,我们要处理全局异常。全局异常在web又分为:已知异常,未知异常。

    已知异常:就是我们能处理的,俗称BUG。

    未知异常:就是开发者不能处理的异常,要用日志记录下来。

    而在SpringBoot中异常处理,SpringBoot已经提供了

    就是@ControllerAdivce 这个注解

    我们来看下这个注解的源码

      

    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 {};
    }

    这个注解只能作用类上

    @ControllerAdvice是一个特殊的@Component,用于标识一个类,这个类中被以下三种注解标识的方法:@ExceptionHandler@InitBinder@ModelAttribute,将作用于所有的@Controller类的接口上

    @InitBinder的作用
      作用:注册属性编辑器,对HTTP请求参数进行处理,再绑定到对应的接口,比如格式化的时间转换等。应用于单个@Controller类的方法上时,仅对该类里的接口有效。与@ControllerAdvice组合使用可全局生效
    @ControllerAdvice
    public class ActionAdvice {
        
        @InitBinder
        public void handleException(WebDataBinder binder) {
            binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
        }
    }
    
    作者:空夜
    链接:https://juejin.im/post/6844903826412011533
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    @ModelAttribute

      作用:绑定数据

    @ControllerAdvice
    public class ActionAdvice {
        
        @ModelAttribute
        public void handleException(Model model) {
            model.addAttribute("user", "zfh");
        }
    }
    
    作者:空夜
    链接:https://juejin.im/post/6844903826412011533
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    在接口中获取前面绑定的参数:

    @RestController
    public class BasicController {
        
        @GetMapping(value = "index")
        public Map index(@ModelAttribute("user") String user) {
            //...
        }
    }
    
    作者:空夜
    链接:https://juejin.im/post/6844903826412011533
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    @ExceptionHandler

    作用:统一异常处理,也可以指定要处理的异常类型

    来看一下源码

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ExceptionHandler {
    
        /**
         * Exceptions handled by the annotated method. If empty, will default to any
         * exceptions listed in the method argument list.
         */
        Class<? extends Throwable>[] value() default {};
    
    }
    Class<? extends Throwable>[] value() default {};  是泛型类数组 继承 Throwable 
    现在让我们回到java中的异常

     Error表示严重的错误,程序对此一般无能为力,出现Error异常程序都不能运行了,还处理个毛。

    所以在SpringBoot中全局处理异常Exception。

    Exception 分为 checkedException 和 RuntimeException

    Checked Exception: 指的是不能恢复,必须要被使用者来处理的一类异常,如果不捕获,那么编译会报错。例如,IOException。

    Unchecked Exception: 指的是在运行时才会导致程序奔溃的异常,编译时候并不会报错。例如,Runtime Exception

    所以在web中已知异常HttpException 通常继承RuntimeException异常。

    package com.lin.missyou.core;
    
    
    import com.lin.missyou.core.configuration.ExceptionCodeConfiguration;
    import com.lin.missyou.exception.http.HttpException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    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;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 全局异常处理
     */
    @ControllerAdvice
    public class GlobalExceptionAdvice {
    
        @Autowired
        private ExceptionCodeConfiguration codeConfiguration;
        
        //未知异常处理
        @ExceptionHandler(value = Exception.class)
        @ResponseBody
        @ResponseStatus
        public UnifyResponse handleException(HttpServletRequest request,Exception e){
            String errorUrl =request.getMethod()+ " " +request.getRequestURL();
            UnifyResponse unifyResponse = new UnifyResponse(9999,"服务器未知错误",errorUrl);
            return unifyResponse;
        }
        
        //已知异常处理
        @ExceptionHandler(value = {HttpException.class,})
        public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest request, HttpException e){
    
            String errorUrl =request.getMethod()+ " " +request.getRequestURI();
    
            String message = codeConfiguration.getMessage(e.getCode());
    
            UnifyResponse unifyResponse = new UnifyResponse(e.getCode(),message,errorUrl);
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            HttpStatus status = HttpStatus.resolve(e.getHttpStatusCode());
    
            ResponseEntity<UnifyResponse> responseEntity = new ResponseEntity<>(unifyResponse,httpHeaders,status);
    
            return responseEntity;
        }
    
    }
    package com.lin.missyou.core;
    
    /**
     * 统一错误返回
     */
    public class UnifyResponse {
        private int code;
        private String message;
        private String request;
    
        public UnifyResponse(String request) {
            this.request = request;
        }
    
        public UnifyResponse(int code, String message, String request) {
            this.code = code;
            this.message = message;
            this.request = request;
    
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public String getRequest() {
            return request;
        }
    
        public void setRequest(String request) {
            this.request = request;
        }
    }

    在上面代码中要解释的注解@ResponseStatus

    这里主要就是改变响应体的状态码 例如:500 服务器错误

    这里的HttpException 是自定义的继承RuntimeException

    package com.lin.missyou.exception.http;
    
    
    public class HttpException extends RuntimeException {
        protected int code;
        protected int httpStatusCode=500;
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public int getHttpStatusCode() {
            return httpStatusCode;
        }
    
        public void setHttpStatusCode(int httpStatusCode) {
            this.httpStatusCode = httpStatusCode;
        }
    }
  • 相关阅读:
    黑产上演《三体》剧情:蠕虫病毒入侵手机群发“钓鱼”短信
    安天AVL联合小米MIUI首擒顽固病毒“不死鸟”
    阿里云存储OSS服务端签名客户端直传
    mariadb 安装配置
    NPOI 打印设置
    windows2008 r2 网络负载均衡搭建
    SqlServer数据库技巧
    达梦数据库备份还原
    ASP.NET CORE Docker发布记录
    DataReader转换
  • 原文地址:https://www.cnblogs.com/wuheng-123/p/13885726.html
Copyright © 2011-2022 走看看