SpringBoot-(9)自定义异常和全局异常

it2023-05-09  79

自定义异常和全局异常

异常是什么在这里不多做解释了。在实际的项目开发中,程序会发生各种异常,如果这些异常不做处理,将会直接暴露给前端,即暴露给用户,降低体验质量,也留下安全隐患。对可能发生的异常进行处理和日志记录,能保证后端程序的正常运行,也能给用户带来更好的体验。采用全局异常将减少try catch这样重复的异常处理,减少代码量,防止漏网的异常没被处理。

1、自定义异常

1)创建异常枚举类

package com.example.demo.enums; public class ErrorCode { private ErrorCode() { throw new IllegalStateException("Utility class"); } /** * 我就试一下 */ public static final String HELLO_EXCEPTION = "90000001"; public static final String SERVICE_EXCEPTION = "90000002"; }

2)自定义异常类

package com.example.demo.exceptions; public class AppServiceException extends Exception{ private static final long serialVersionUID = -2416380262384957964L; /** * 错误编码 */ private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public AppServiceException() {} public AppServiceException(final String message) { super(message); } public AppServiceException(final Throwable cause) { super(cause); } public AppServiceException(String code, String message) { this(message); this.code = code; } }

3)项目结构及Resource Bundle的创建

在resource的目录下创建resource bundle。

项目结构:

4)application.yml配置文件

logging: file: name: slf4j-test path: ./logs max-size: 10MB level: root: info config: classpath:logback-gnete.xml spring: messages: basename: messages_zh

5)业务层接口及实现类

interface package com.example.demo.interfaces; import com.example.demo.exceptions.AppServiceException; public interface ExceptionService { void exceptionTest() throws AppServiceException; double GlobalExceptionTest(Integer num); } AbstractService package com.example.demo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; @Service public class AbstractService { // 注入messageSource @Autowired private MessageSource messageSource; public String getMessage(String code, String defaultMsg) { return this.messageSource.getMessage(code, null, defaultMsg, LocaleContextHolder.getLocale()); } public String getMessage(String code) { return this.getMessage(code, ""); } } serviceImp package com.example.demo.service; import com.example.demo.enums.ErrorCode; import com.example.demo.exceptions.AppServiceException; import com.example.demo.interfaces.ExceptionService; import org.springframework.stereotype.Service; @Service public class ExceptionServiceImp extends AbstractService implements ExceptionService { @Override public void exceptionTest() throws AppServiceException { throw new AppServiceException(ErrorCode.HELLO_EXCEPTION, this.getMessage(ErrorCode.HELLO_EXCEPTION)); } @Override public double GlobalExceptionTest(Integer num){ return (double) num / 0; } }

6)返回的结果类

package com.example.demo.pojo; import java.io.Serializable; public class ReponseResult<T> implements Serializable { private static final long serialVersionUID = 9191892693219217387L; private static final String RESP_CODE_SUCCESS = "00000000"; private String code; private boolean success; private String message; private T data; public ReponseResult() { } public String getCode() { return this.code; } public void setCode(String code) { this.code = code; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public T getData() { return this.data; } public void setData(T data) { this.data = data; } public boolean isSuccess() { return this.success; } public void setSuccess(boolean success) { this.success = success; } public static <T> ReponseResult<T> success(T data) { ReponseResult<T> result = new ReponseResult(); result.setCode("00000000"); result.setMessage("成功"); result.setSuccess(true); result.setData(data); return result; } public static <T> ReponseResult<T> fail(String code, String message, T data) { ReponseResult<T> result = new ReponseResult(); result.setCode(code); result.setData(data); result.setMessage(message); result.setSuccess(false); return result; } public static <T> ReponseResult<T> fail(String code, String message) { ReponseResult<T> result = new ReponseResult(); result.setCode(code); result.setMessage(message); result.setSuccess(false); result.setData((T) null); return result; } }

7)全局异常处理handler

package com.example.demo.handler; import com.example.demo.enums.ErrorCode; import com.example.demo.exceptions.AppServiceException; import com.example.demo.pojo.ReponseResult; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(value = AppServiceException.class) @ResponseBody public ReponseResult appServiceExceptionHandler(AppServiceException e){ log.error("发生业务异常!原因是:{}",e.getMessage()); return ReponseResult.fail(e.getCode(),e.getMessage()); } @ExceptionHandler(value = RuntimeException.class) @ResponseBody public ReponseResult appServiceRuntimeException(RuntimeException e){ log.error("发生运行时业务异常!原因是:{}",e.getMessage()); return ReponseResult.fail(String.valueOf(400),e.getMessage()); } @ExceptionHandler(value = NullPointerException.class) @ResponseBody public ReponseResult noPermissionException(NullPointerException e){ log.error("空指针异常!原因是:{}",e.getMessage()); return ReponseResult.fail("90000003","数据不存在"); } @ExceptionHandler(value = Exception.class) @ResponseBody public ReponseResult commonExceptionHandler(Exception e){ log.error("通用异常!原因是:{}",e.getMessage()); return ReponseResult.fail(ErrorCode.SERVICE_EXCEPTION,e.getMessage()); } } @ControllerAdvice 捕获 Controller 层抛出的异常,如果添加 @ResponseBody 返回信息则为JSON 格式。@RestControllerAdvice 相当于 @ControllerAdvice 与 @ResponseBody 的结合体。@ExceptionHandler 统一处理一种类的异常,减少代码重复率,降低复杂度。

8)控制层

package com.example.demo.controller; import com.example.demo.exceptions.AppServiceException; import com.example.demo.interfaces.ExceptionService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class TestController { @Autowired ExceptionService exceptionService; @GetMapping("/exceptionTest") public String test2() throws AppServiceException { log.debug("自定义异常处理"); exceptionService.exceptionTest(); return "ok"; } @GetMapping("/GlobalExceptionTest") public double test2(Integer num) throws AppServiceException { log.debug("全局异常处理"); return exceptionService.GlobalExceptionTest(num); } }

9)异常处理结果

最新回复(0)