统一处理异常demo

异常定义

**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;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值