本系列文章介绍从0开始搭建一个基于分布式的医疗挂号系统。本次四篇文章完成了
医院设置微服务 | 模块搭建医院设置微服务 | 接口开发通用模块 | 整合Swagger2通用模块 | 统一返回结果、统一异常处理、统一日志处理医院设置微服务模块
的后端接口,为了方便开发,对接口的返回结果
、全局异常
、全局日志
进行了统一处理。 同时,为了方便进行访问测试,还整合了Swagger2工具
,这些通用的模块中,除了全局日志
被放在医院设置微服务模块的配置资源中,其余都统一被抽取在common模块中。具体实现可参考下面文章:作者:Hudie
微信公众号/CSDN博客:编程一只蝶
公众号文章会比博客早1到2天,欢迎关注,每天开心~
项目已开源至gitee:https://gitee.com/guo-qianliang/yygh_parent
项目已开源至github:https://github.com/Guoqianliang/yygh_parent
一、统一返回结果
在实际开发中,是一个后端团队一起开发,每个人做不同的模块,开发不同的接口,最终进行调用进而显示。因此可以把所有返回结果做一个统一的约定。让所有的接口都返回相同的数据格式,这样利于前端的显示与解析。
上图这一操作需要通过统一返回结果类 和统一返回结果状态信息类 来实现。
1.统一返回结果类
/** * 全局统一返回结果类 */ @Data @ApiModel(value = "全局统一返回结果") public class Result{ @ApiModelProperty(value = "返回码") private Integer code; @ApiModelProperty(value = "返回消息") private String message; @ApiModelProperty(value = "返回数据") private T data; public Result() { } protected static Result build(T data) { Result result = new Result (); if (data != null) { result.setData(data); } return result; } public static Result build(T body, ResultCodeEnum resultCodeEnum) { Result result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static Result build(Integer code, String message) { Result result = build(null); result.setCode(code); result.setMessage(message); return result; } public static Result ok() { return Result.ok(null); } /** * 操作成功 * @param data * @param * @return */ public static Result ok(T data) { Result result = build(data); return build(data, ResultCodeEnum.SUCCESS); } public static Result fail() { return Result.fail(null); } /** * 操作失败 * @param data * @param * @return */ public static Result fail(T data) { Result result = build(data); return build(data, ResultCodeEnum.FAIL); } public Result message(String msg) { this.setMessage(msg); return this; } public Result code(Integer code) { this.setCode(code); return this; } public boolean isOk() { if (this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) { return true; } return false; } }
2.统一返回状态信息类
/** * 统一返回结果状态信息类 */ @Getter public enum ResultCodeEnum { SUCCESS(200, "成功"), FAIL(201, "失败"), PARAM_ERROR(202, "参数不正确"), SERVICE_ERROR(203, "服务异常"), DATA_ERROR(204, "数据异常"), DATA_UPDATE_ERROR(205, "数据版本异常"), LOGIN_AUTH(208, "未登陆"), PERMISSION(209, "没有权限"), CODE_ERROR(210, "验证码错误"), // LOGIN_MOBLE_ERROR(211, "账号不正确"), LOGIN_DISABLED_ERROR(212, "改用户已被禁用"), REGISTER_MOBLE_ERROR(213, "手机号已被使用"), LOGIN_AURH(214, "需要登录"), LOGIN_ACL(215, "没有权限"), URL_ENCODE_ERROR(216, "URL编码失败"), ILLEGAL_CALLBACK_REQUEST_ERROR(217, "非法回调请求"), FETCH_ACCESSTOKEN_FAILD(218, "获取accessToken失败"), FETCH_USERINFO_ERROR(219, "获取用户信息失败"), //LOGIN_ERROR( 23005, "登录失败"), PAY_RUN(220, "支付中"), CANCEL_ORDER_FAIL(225, "取消订单失败"), CANCEL_ORDER_NO(225, "不能取消预约"), HOSCODE_EXIST(230, "医院编号已经存在"), NUMBER_NO(240, "可预约号不足"), TIME_NO(250, "当前时间不可以预约"), SIGN_ERROR(300, "签名错误"), HOSPITAL_OPEN(310, "医院未开通,暂时不能访问"), HOSPITAL_LOCK(320, "医院被锁定,暂时不能访问"), ; private Integer code; private String message; private ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } }
二、统一异常处理
spring boot 默认情况下会将异常映射到 /error 进行异常处理,这样的提示十分不友好,下面使用自定义异常处理,可以提供更友好的展示。
1.自定义异常类
/** * 自定义全局异常类 * */ @Data @ApiModel(value = "自定义全局异常类") public class YyghException extends RuntimeException { @ApiModelProperty(value = "异常状态码") private Integer code; /** * 通过状态码和错误消息创建异常对象 * @param message * @param code */ public YyghException(String message, Integer code) { super(message); this.code = code; } /** * 接收枚举类型对象 * @param resultCodeEnum */ public YyghException(ResultCodeEnum resultCodeEnum) { super(resultCodeEnum.getMessage()); this.code = resultCodeEnum.getCode(); } @Override public String toString() { return "YyghException{" + "code=" + code + ", message=" + this.getMessage() + '}'; } }
2.全局异常处理
下面代码中两个方法的@ExceptionHandler
注解,分别传入系统异常Exception类和自定义异常YyghException类,当出现系统异常时会运行系统的Exception方法,当出现自定义异常时会运行YyghException方法。
/** * @Description: 统一异常处理类 * @author Guoqianliang * @date 20:56 - 2021/4/7 */ @ControllerAdvice public class GlobalExceptionHandler { /** * 全局异常处理 * @param e * @return */ @ExceptionHandler(Exception.class) @ResponseBody public Result error(Exception e) { e.printStackTrace(); return Result.fail(); } /** * 自定义异常处理 * @param e * @return */ @ExceptionHandler(YyghException.class) @ResponseBody public Result error(YyghException e) { e.printStackTrace(); return Result.fail(); } }
使用自定义异常时,不会自动调用,需要手动抛出异常,举例如下:
三、统一日志处理
日志记录器(Logger)的行为是分等级的,常用的4个级别如下:
DEBUG < INFO < WARN < ERROR
级别越高,打印的信息越多。默认情况下,springboot从控制台打印出来的日志级别只有INFO及以上级别,通过:logging.level.root=debug
可以修改日志级别。
下面给出一个日志模块,通过此模板可以将日志持久化到本地文件:
logback INFO ${CONSOLE_LOG_PATTERN} UTF-8 ${log.path}/log_info.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log 100MB 15 INFO ACCEPT DENY ${log.path}/log_warn.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log 100MB 15 warn ACCEPT DENY ${log.path}/log_error.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log 100MB 15 ERROR ACCEPT DENY
以上就是实战分布式医疗挂号通用模块统一返回结果异常日志处理的详细内容,更多关于分布式医疗挂号统一返回结果异常日志处理的资料请关注脚本之家其它相关文章!