**1. 通用异常:**就是系统产生的异常
(1)状态码
(2)提示信息
/***
* 通用异常定义
*/
public enum CommonException {
SYSTEM_EXCEPTION(-1,"系统繁忙,请稍后重试");
private Integer code;
private String message;
CommonException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
**2.业务异常:**如用户登录失败等
(1) 状态码
(2) 提示信息
/***
* 用户业务异常
*/
public enum UserException {
USER_PASSWORD_ERROR(1001,"用户名或密码错误");
private Integer code;
private String message;
UserException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
业务中调用
此处的ReturnResultUtils.returnFail方法是我自己定义的一个返回值的方法,可以查看[统一返回数据](https://blog.csdn.net/qq_40664795/article/details/105570986)
ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),Com
monException.SYSTEM_EXCEPTION.getMessage());
实现步骤
① 编写拦截器,拦截抛出的异常
/***
* 异常统一处理的拦截器
*/
public class ExceptionInterceptor implements HandlerInterceptor{
/**
* 方法处理前
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");//这一步主要是前后端分离统一在方法处理前进行拦截解决跨域问题
return true;//true开启拦截功能
}
/**
* 方法处理后,返回前
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
/***
* 方法处理完成后
* @param request
* @param response
* @param o
* @param e
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
//出现异常进行处理
if(EmptyUtils.isNotEmpty(e)){
response.setContentType("text/html;charset=UTF-8");//设置返回值的编码格式
PrintUtil printUtil=new PrintUtil(response); //自己封装的一个输出流工具,由于该方法是void,所以不能把异常return回去,通过流的方式处理
ReturnResult returnResult=ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),CommonException.SYSTEM_EXCEPTION.getMessage());//返回异常信息
printUtil.print(JSONObject.toJSON(returnResult));//转成JSONObject
}
}
}
printUtil工具
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintUtil {
//打印日志
static Logger logger=Logger.getLogger(PrintUtil.class);
public HttpServletResponse response;
public PrintUtil(HttpServletResponse response, String contentType){
this.response=response;
this.response.setContentType(contentType);
}
public PrintUtil(HttpServletResponse response){
this.response=response;
}
public void print(Object msg){
PrintWriter writer=null;
try {
if(null != response){
//如果系统打开了outputStream 那么将其关闭
writer=new PrintWriter(response.getOutputStream());
String temp=new String(String.valueOf(msg));
writer.write(temp);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
writer.close();
}
}
}
引入处理json依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
捕获了异常进行处理
/***
* 方法处理完成后
* @param request
* @param response
* @param o
* @param e
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
//出现异常进行处理
if(EmptyUtils.isNotEmpty(e)){
response.setContentType("text/html;charset=UTF-8");//设置返回值的编码格式
PrintUtil printUtil=new PrintUtil(response); //自己封装的一个输出流工具,由于该方法是void,所以不能把异常return回去,通过流的方式处理
ReturnResult returnResult=ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),CommonException.SYSTEM_EXCEPTION.getMessage());//返回异常信息
printUtil.print(JSONObject.toJSON(returnResult));//转成JSONObject
}
}
第3步
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/***
* 配置拦截器
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
/**
* 把ExceptionInterceptor异常交给springIOC管理,如果定义了多个异常类,那也要像这样添加多个
* @return
*/
@Bean
public ExceptionInterceptor exceptionInterceptor(){
return new ExceptionInterceptor();
}
/**
* 定义的登录异常信息
* @return
*/
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
/**
* 要实现WebMvcConfigurerAdapter的addInterceptors这个方法
* 在ExceptionInterceptor异常里凡是api/后面的都进行拦截
* 在LoginInterceptor异常里凡是api/v/后面的都进行拦截
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(exceptionInterceptor()).addPathPatterns("/api/**");
registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/v/**");
super.addInterceptors(registry);
}
}
在业务中处理异常不再需要try-cartch进行捕获异常了,直接抛出即可(也就是有异常不处理,抛给拦截器进行统一处理),应该如果有异常会在拦截器拦截时进行拦截处理
/***
* 根据用户名和密码生成token
* @param phone
* @param password
* @return
*/
public ReturnResult validateToken(String phone, String password)throws Exception{
ReturnResult returnResult=null;
QgUser qgUser=null;
String token=null;
qgUser=qgUserService.queryQgUserByPhoneAndPwd(phone,password);
if(null!=qgUser){
//如果验证成功,生成token放在redis
String oldToken=redisUtil.getStr(qgUser.getId());
if(EmptyUtils.isNotEmpty(oldToken)){
redisUtil.del(oldToken);
redisUtil.del(qgUser.getId());
}
token=Constants.tokenPrefix+TokenUtils.createToken(qgUser.getId(),qgUser.getPhone());
redisUtil.setStr(token, JSONObject.toJSONString(qgUser), Constants.loginExpire);
redisUtil.setStr(qgUser.getId(), token,Constants.loginExpire);
Map<String,Object> result=new HashMap<String,Object>();
result.put("token",token);
returnResult= ReturnResultUtils.returnSuccess(result);
}else{
returnResult= ReturnResultUtils.returnFail(UserException.USER_PASSWORD_ERROR.getCode(),UserException.USER_PASSWORD_ERROR.getMessage());
}
return returnResult;
}