ERROR:严重问题,我们无法处理
EXCEPTION:RuntimeException 编译期不检查,出现问题需要我们修改代码
非RuntimeException(CheckedException无这个异常类) 编译期必须处理,否则程序无法编译
自定义异常继承Excepition默认为非RuntimeExcepition。
异常 可以处理 用非RuntimeException 举例:处理文件,文件路径错误。
无能为力 RuntimeException 举例:数据库请求数据,数据库无此数据。
在编写后台时,为了方便前端快速定位错误,仅仅使用java自带的异常是不够的。需要自定义处理异常。
为了便于显示,本文统一错误响应格式:
//统一错误响应 { code:10001 message:xxxx request:GET url }
UnifyResponse.class
@Getter @Setter @AllArgsConstructor public class UnifyResponse { private int code; private String message; private String request; }
本文将异常分为两种:
未知异常:对于前端开发者和用户 都是无意义。通常是服务端开发者代码逻辑问题。
不需要将详细信息返还给前端和用户,可以统一显示服务器内部错误
已知异常
定义已知异常:
HttpException.class
public class HttpException extends RuntimeException { protected Integer code; protected Integer httpStatusCode = 500; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public Integer getHttpStatusCode() { return httpStatusCode; } public void setHttpStatusCode(Integer httpStatusCode) { this.httpStatusCode = httpStatusCode; } }
NotFoundExcepiton.class
public class NotFoundException extends HttpException { public NotFoundException(int code){ this.httpStatusCode = 404; this.code = code; } }
处理异常:
GlobalExceptionAdvice.class:
@ControllerAdvice public class GlobalExceptionAdvice { @Autowired private ExceptionCodeConfiguration exceptionCodeConfiguration; //未知异常 错误码就直接硬编码为9999 @ResponseBody @ExceptionHandler(value = Exception.class) //如果不加这个注解,传回前端的http状态码会显示200 ok @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) public UnifyResponse handleException(HttpServletRequest req, Exception e) { UnifyResponse message = new UnifyResponse(9999,"服务器异常",req.getMethod() + ' ' + req.getRequestURI()); //未知异常方便调试,产品上线可以去掉 System.out.println(e); return message; } //已知异常 Http异常其中包含多种异常 错误码由程序员传入例如: throw new NotFoundException(10001); //为什么不和上面未知异常一样使用@ResponseHandler 因为已知异常有很多种,状态码不一样,不能直接硬编码 //解决办法:在处理各种已知异常的类中添加http状态码,在返回的response中自己添加。使用ResponseEntity @ExceptionHandler(HttpException.class) public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest req, HttpException e) { UnifyResponse message = new UnifyResponse(e.getCode(),exceptionCodeConfiguration.getMessage(e.getCode()),req.getMethod() + ' ' + req.getRequestURI()); HttpHeaders httpHeaders = new HttpHeaders(); HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode()); ResponseEntity<UnifyResponse> r = new ResponseEntity<>(message,httpHeaders,httpStatus); return r; } }
配置类
已知异常的错误码和信息不要硬编码在异常类中,要善用properties配置类
exception-code.properties
liu.codes[0] = ok liu.codes[999] = 服务器未知异常 liu.codes[10000] = 通用错误 liu.codes[10001] = 通用参数错误 liu.codes[10002] = 资源未找到 liu.codes[10003] = 没有找到合适的登陆处理方法 liu.codes[10004] = 令牌不合法或者过期 liu.codes[10005] = 用户未被授权 liu.codes[10006] = 登陆失败 liu.codes[20000] = 用户类通用错误 liu.codes[20001] = 用户已存在 liu.codes[20002] = 用户不存在 liu.codes[20003] = 用户密码错误 liu.codes[20004] = 获取用户wx openid失败 liu.codes[30000] = 商品类通用错误 liu.codes[30001] = 分类不存在 liu.codes[30002] = 商品信息不存 liu.codes[30003] = 主题不存在 liu.codes[30004] = complexity参数错误 liu.codes[30005] = Banner类资源不存在 liu.codes[30006] = 当前暂不支持级联获取sku-list liu.codes[30007] = 当前暂不支持级联获取spu-list,请调用其他接口 liu.codes[30008] = 当前没有更多的商品信息了 liu.codes[30009] = Grid分类不存在 liu.codes[30010] = 请求的单品列表不存在 liu.codes[30011] = 请求的商品SaleExplain不存在
读取配置类:
ExceptionCodeConfiguration.class
@ConfigurationProperties(prefix = "liu") @PropertySource(value = "classpath:/config/exception-code.properties") @Component public class ExceptionCodeConfiguration { private Map<Integer,String> codes =new HashMap<>(); public Map<Integer, String> getCodes() { return codes; } public void setCodes(Map<Integer, String> codes) { this.codes = codes; } public String getMessage(int code){ return codes.get(code); } }
解决读取properties中文乱码
idea:
- File->setting->File Encoding 将Properties Files改为UTF-8编码,并将Transparent native-to-ascii 打勾。
- 可能上述操作后properties文件全部乱码,把内容删除在重新输入就可以了。
来源:https://www.cnblogs.com/chauncyL/p/12535971.html