SpringBoot 全局处理
全局消息处理
通常情况下,我们系统并不会考虑将文字描述等信息通过后台返回,我这样设计的好处就是如果以后需要前后端分离,并不会对整体结构造成影响。
/**
* 异常枚举类
*
* @author Tellsea
* @date 2019/7/13
*/
@AllArgsConstructor
public enum StatusEnums {
/**
* 业务枚举
*/
LAYUI_SUCCESS(0, "加载成功"),
SAVE_SUCCESS(200, "新增成功"),
DELETE_SUCCESS(200, "删除成功"),
UPDATE_SUCCESS(200, "修改成功"),
SELECT_SUCCESS(200, "查询成功"),
SAVE_ERROR(500, "新增失败"),
DELETE_ERROR(500, "删除失败"),
UPDATE_ERROR(500, "修改失败"),
SELECT_ERROR(500, "查询失败"),
/**
* 系统枚举
*/
UNAUTHORIZED(403, "未授权"),
NOT_FOUND(404, "请求资源不存在"),
USER_NOT_FOUND(500, "用户不存在"),
PARAM_NOT_NULL(500, "参数不能为空"),
CAPTCHA_ERROR(500, "验证码错误"),
PASSWORD_ERROR(500, "密码错误"),
SERVER_ERROR(500, "服务器累了,休息一会吧!"),
;
@Setter
private int code;
@Setter
private String info;
@Override
public int getCode() {
return code;
}
@Override
public String getInfo() {
return info;
}
}
扩展枚举
通过上面的配置状态码与信息,能解决所有的返回问题,同时衍生出了新的问题,假设我有一千个业务,针对业务的详细描述大概就是四千种,同时在一个类中定义所有的状态枚举就不符合我们的开发逻辑,高耦合,低内聚。
首先定义一个根接口,然后让相关的枚举类继承该接口,例如状态枚举、系统枚举、商品枚举等
/**
* 枚举根接口
*
* @author Tellsea
* @date 2019/8/5
*/
public interface BaseEnums {
/**
* 获得状态码
*
* @return
*/
int getCode();
/**
* 获得消息
*
* @return
*/
String getInfo();
}
改造我们上面的异常枚举类
public enum StatusEnums implements BaseEnums {
}
最后在使用时,我们的枚举参数统一使用 BaseEnums ,这样就可以传各种枚举的数据进行返回了。
全局响应处理
通常情况下,我们将后台的所有返回值都指定到特定的格式中,这样让整个开发团队协调性得到很大的提升,在前后端分离中能看出最显著的效果。下面是定义的全局返回结果集,为了提高效率,采用的是单例模式。(这里有一个坑,前后端分离网络卡顿的时候,返回值可能会错乱)
/**
* 全局返回结果集
*
* @author Tellsea
* @date 2019/7/13
*/
@Data
public class ResponseResult {
private int code;
private String message;
private Object data;
private static volatile ResponseResult instance;
public static ResponseResult build(BaseEnums enums) {
ResponseResult result = getInstance();
result.code = enums.getCode();
result.message = enums.getInfo();
result.data = null;
return result;
}
public static ResponseResult build(BaseEnums enums, Object data) {
ResponseResult result = getInstance();
result.code = enums.getCode();
result.message = enums.getInfo();
result.data = data;
return result;
}
public static ResponseResult getInstance() {
if (null == instance) {
synchronized (ResponseResult.class) {
if (null == instance) {
instance = new ResponseResult();
}
}
}
return instance;
}
}
全局异常处理
通常情况下,我们都会重写系统默认的异常处理,修改抛出异常后的异常通知,从而达到对用户的友好提示,增加用户的体验度。
- 自定义全局异常
/**
* 全局异常
*
* @author Tellsea
* @date 2019/7/13
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class GlobalException extends RuntimeException {
private BaseEnums baseEnums;
}
- 全局异常处理器
/**
* 全局异常处理
*
* @author Tellsea
* @date 2019/7/13
*/
@Slf4j
@ControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandle {
@ExceptionHandler(value = Exception.class)
public String exception(Exception e, Model model) {
model.addAttribute("class", e.getClass());
model.addAttribute("message", e.getMessage());
log.error("【错误原因】{}", e.getClass());
log.error("【错误描述】{}", e.getMessage());
e.printStackTrace();
return "admin/error";
}
@ExceptionHandler(value = GlobalException.class)
public String globalExceptionHandle(GlobalException e, Model model) {
model.addAttribute("class", e.getClass());
model.addAttribute("message", e.getMessage());
log.error("【错误原因】{}", e.getClass());
log.error("【错误描述】{}", e.getMessage());
e.printStackTrace();
return "admin/error";
}
}
提示:这里结合了全局消息处理、全局响应处理模块