`

ExceptionHandler结合HandlerInterceptorAdapter

阅读更多
spring项目中,要统一处理异常,ExceptionHandler是必须实现的,但是@ExceptionHandler是不能拦截HandlerInterceptorAdapter.preHandle()方法抛出的异常的,根本原因还要看执行顺序:Filter->Interceptor->ControllerAdvice->Aspect,preHandle不会受ControllerAdvice影响。

所以Filter我们可以可以通过跳转的方式特殊处理:
request.getRequestDispatcher("/exception/401").forward(request,response);

同时需要实现ExceptionController

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.publisher.common.vo.Res;
import com.publisher.common.vo.ResultCode;
import com.publisher.exception.ServiceException;


//@Controller
@RestController
@RequestMapping("/exception")
public class ExceptionController {

	@Value("${publisher.privateKey}")
	private String privateKey;
	
	
	@RequestMapping("/401")
    @ResponseBody
    public Res handle() {
        throw new ServiceException(ResultCode.UNAUTHORIZED);
    }
}


HandlerInterceptorAdapter完整代码:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.publisher.utils.JwtUtils;
import com.publisher.utils.SessionUtils;

import io.jsonwebtoken.Claims;

@Component
public class LoginFilter  extends  HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		String path = request.getServletPath();

		if(StringUtils.equals("/v1/getToken", path)||StringUtils.equals("/index.html", path)){//白名单
			return true;
		}
		String token  = request.getHeader("token");
		if(StringUtils.isBlank(token)){
//			throw new ServiceException(ResultCode.UNAUTHORIZED);
			 request.getRequestDispatcher("/exception/401").forward(request,response);
			return false;
		}
			try{
			Claims aa = JwtUtils.checkJWT(token);
			SessionUtils.setMember(aa);
			}catch(Exception e){
				request.getRequestDispatcher("/exception/401").forward(request,response);
				return false;
//				throw new ServiceException(ResultCode.UNAUTHORIZED);
			}
		return true;
	}
	
	
}



ExceptionHandler 异常统一统一处理类

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.publisher.common.vo.Res;
import com.publisher.common.vo.ResultCode;
import com.publisher.exception.ServiceException;

import java.util.regex.Pattern;

@ControllerAdvice
public class ExceptionHandler {

	Pattern p = Pattern.compile("[\u4e00-\u9fa5]");

    @org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Res handle(MethodArgumentNotValidException e) {
        String message = ResultCode.FAILED.getMsg();
        if (e.getBindingResult().getAllErrors().size() > 0) {
            message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        }
//        Matcher matcher = p.matcher(message);
//        if (!matcher.find()) {
//            e.printStackTrace();
//        }
        return Res.failed(message);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Res handle(IllegalArgumentException ex) {
        String message = ex.getMessage();
//        Matcher matcher = p.matcher(message);
//        if (!matcher.find()) {
            ex.printStackTrace();
//        }
        return Res.failed(message);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Res handle(Exception e) {
        String message = e.getMessage();
//        Matcher matcher = p.matcher(message);
//        if (!matcher.find()) {
            e.printStackTrace();
//        } 
        return Res.failed(message);
    }

//ServiceException业务异常,可预知业务错误,不输出异常堆栈,比如说授权失败。
@org.springframework.web.bind.annotation.ExceptionHandler(ServiceException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Res handle(ServiceException e) {
        return Res.failed(e.getResultCode());
    }
分享到:
评论

相关推荐

    SpringMVC 中的拦截器与异常处理

    通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`抽象类,开发者可以定义自己的拦截器。拦截器通常用于实现如登录检查、权限验证、日志记录、性能统计等跨切面的功能。 1. 拦截器的注册:拦截...

    基于SpringBoot企业级完善架构

    6. **ExceptionHandler(错误消息统一处理)**:在SpringBoot应用中,通过全局异常处理器(@ControllerAdvice + @ExceptionHandler)可以统一处理所有控制器层的异常,提供友好的错误提示,同时便于日志记录和问题...

    spring 源码

    通过@ControllerAdvice和@ExceptionHandler注解,可以定义全局的异常处理器,统一处理应用程序可能出现的各种异常。 总的来说,Spring MVC源码的阅读可以帮助我们理解请求处理的完整流程,以及Spring如何优雅地解耦...

    跟开涛学SpringMVC(4.6)Controller接

    在本课程"跟开涛学SpringMVC(4.6)Controller接...在学习过程中,结合"跟开涛学SpringMVC(4.6)Controller接口控制器详解(6)Java开发Java经验技巧共10页.pdf"这份资料,你将能深入理解并掌握SpringMVC的核心概念。

    Springmvc4.0.3

    7. **异常处理**:Spring MVC允许通过`@ExceptionHandler`注解定义全局或特定异常的处理方法,从而提供优雅的错误页面和错误信息。 8. **模板引擎支持**:Spring MVC 4.0.3支持多种模板引擎,如JSP、FreeMarker、...

    powernode_springmvc源码.zip

    Spring MVC 提供了@ControllerAdvice 和 @ExceptionHandler 注解,允许开发者统一管理全局异常,提高代码的可维护性。 9. **第十三章:权限拦截器** "ch12-interceptor-permission.rar"专注于权限验证的拦截器实现...

    springMVC的深入研究

    Spring3 MVC支持自定义拦截器,可以通过实现`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`类来创建。拦截器可以用于执行预处理操作(如登录验证)、后处理操作等。 #### 十、全局异常处理 Spring3 ...

Global site tag (gtag.js) - Google Analytics