异常篇--全局处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/smd2575624555/article/details/81235434

全局异常处理

最近搭建项目,对于异常进行统一包装处理,统一包装异常以json的形式进行展示,保持代码结构优雅,性能稳定,不将原生的exception展示给前端,保持约定,统一格式,做工程化代码结构。

异常处理一共包括两种,系统自动抛出异常,人为手动抛出异常。统一将异常在collection层进行捕捉,在以统一的json格式进行展示。

因为入参校验采用注解形式,将错误信息捕捉,并返回前端原因,有助于使用者理解。

全局异常捕捉code

    import java.net.ConnectException;
    import java.net.SocketException;
    import java.util.ArrayList;
    import java.util.List;

    import javax.validation.ValidationException;

    import org.apache.commons.lang3.StringUtils;
    import org.springframework.http.HttpStatus;
    import org.springframework.validation.BindException;
    import org.springframework.validation.FieldError;
    import org.springframework.validation.ObjectError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    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 org.springframework.web.client.HttpClientErrorException;
    import org.springframework.web.client.HttpServerErrorException;

    import com.ds.face.pojo.dto.ResponseDTO;

    import lombok.extern.slf4j.Slf4j;

    /**
     * 全局异常处理
     * 
     * @author Simon
     *
     */
    @ControllerAdvice
    @Slf4j
    public class GlobalExceptionHandler {

        @ExceptionHandler(NullPointerException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        public @ResponseBody ResponseDTO handleNullPointerException(NullPointerException ex) {
            log.info(ex.getMessage());
            System.out.println(ex);
            return ResponseDTO.builder().status(400).message("ERROR_BAD_PARAM").body(ex.getMessage()).build();
        }

        @ExceptionHandler(ValidationException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        public @ResponseBody ResponseDTO handleIllegalArgumentException(ValidationException ex) {
            log.error("参数绑定失败", ex);
            return ResponseDTO.builder().status(400).message("ERROR_BAD_PARAM").body(ex.getMessage()).build();
        }

        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ResponseBody
        public ResponseDTO handleException(final MethodArgumentNotValidException ex) {
            log.error("参数绑定失败", ex);
            return this.handleException(new BindException(ex.getBindingResult()));
        }

        @ExceptionHandler(IllegalArgumentException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        public @ResponseBody ResponseDTO handleIllegalArgumentException(IllegalArgumentException ex) {
            log.error("类型转化错误", ex);
            return ResponseDTO.builder().status(400).message("ERROR_TYPE_CONVERSION").body(ex.getMessage()).build();
        }

        @ExceptionHandler(ControlledException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        public @ResponseBody ResponseDTO handleControlledException(ControlledException ex) {
            log.error("可控制错误", ex);
            return ResponseDTO.builder().status(ex.getErrorCode()).message(ex.getMessage()).body(ex.getContent()).build();
        }

        @ExceptionHandler(HttpConnectionException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public @ResponseBody ResponseDTO handleHttpConnectionException(HttpConnectionException ex) {
            log.error("访问上游系统失败", ex);
            return ResponseDTO.builder().status(500).message("ERROR_RESPONSE").body(ex.getMessage()).build();
        }

        @ExceptionHandler(HttpServerErrorException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public @ResponseBody ResponseDTO handleHttpServerErrorException(HttpServerErrorException ex) {
            log.error("访问上游系统失败", ex);
            return ResponseDTO.builder().status(500).message("ERROR_CONNECTION_FAIL")
                    .body("The parent system connection refused").build();
        }

        @ExceptionHandler(HttpClientErrorException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public @ResponseBody ResponseDTO handleHttpServerErrorException(HttpClientErrorException ex) {
            log.error("访问上游系统失败", ex);
            return ResponseDTO.builder().status(500).message("ERROR_CONNECTION_FAIL")
                    .body("The parent system connection refused").build();
        }

        @ExceptionHandler(ConnectException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public @ResponseBody ResponseDTO handleConnectException(ConnectException ex) {
            log.error("访问上游系统失败", ex);
            return ResponseDTO.builder().status(500).message("ERROR_CONNECTION_FAIL")
                    .body("The parent system connection refused").build();
        }

        @ExceptionHandler(SocketException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public @ResponseBody ResponseDTO handleSocketException(SocketException ex) {
            log.error("连接异常", ex);
            return ResponseDTO.builder().status(500).message("ERROR_CONNECTION_FAIL")
                    .body("The parent system connection refused").build();
        }

        @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ExceptionHandler(BindException.class)
        @ResponseBody
        public ResponseDTO handleException(final BindException ex) {
            log.error("参数绑定失败", ex);
            List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
            List<ObjectError> globalErrors = ex.getBindingResult().getGlobalErrors();
            List<String> errors = new ArrayList<>(fieldErrors.size() + globalErrors.size());
            for (FieldError fieldError : fieldErrors) {
                String error = fieldError.getDefaultMessage();
                if (error.contains("NumberFormatException")) {
                    error = fieldError.getField() + ":请输入正确的数字!";
                }
                if (error.contains("ConversionFailedException") && error.contains("annotation.DateTimeFormat")) {
                    StringBuilder buff = new StringBuilder(fieldError.getField());
                    buff.append("时间格式不合法!");
                    error = buff.toString();
                }
                errors.add(error);
            }

            for (ObjectError objectError : globalErrors) {
                String error = objectError.getDefaultMessage();
                errors.add(error);
            }
            return ResponseDTO.builder().status(400).message("ERROR_BAD_PARAM").body(StringUtils.join(errors, "  |  "))
                    .build();
        }

        @ExceptionHandler(SuccessResponse.class)
        @ResponseStatus(HttpStatus.OK)
        public @ResponseBody ResponseDTO handleSuccessResponse(SuccessResponse ex) {
            log.error("成功返回上游问题", ex);
            return ResponseDTO.builder().status(ex.getErrorCode()).message(ex.getMessage()).body(ex.getContent()).build();
        }
    }

自定义异常

    /**
     * 其定义空异常
     * 
     * @author Somin
     * @date 2018年7月05日
     */
    public class ControlledException extends RuntimeException {
        private static final long serialVersionUID = 1L;

        public ControlledException(Integer errorCode, String message, String content) {
            super();
            this.errorCode = errorCode;
            this.message = message;
            this.content = content;
        }
        private Integer errorCode;
        private String message;
        private String content;

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public Integer getErrorCode() {
            return errorCode;
        }

        public void setErrorCode(Integer errorCode) {
            this.errorCode = errorCode;
        }
    }

自定义成功返回值


    public class SuccessResponse extends RuntimeException {
        private static final long serialVersionUID = 1L;

        public SuccessResponse(Integer errorCode, String message, String content) {
            super();
            this.errorCode = errorCode;
            this.message = message;
            this.content = content;
        }

        private Integer errorCode;
        private String message;
        private String content;

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public Integer getErrorCode() {
            return errorCode;
        }

        public void setErrorCode(Integer errorCode) {
            this.errorCode = errorCode;
        }
    }

猜你喜欢

转载自blog.csdn.net/smd2575624555/article/details/81235434