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());
}
分享到:
相关推荐
通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`抽象类,开发者可以定义自己的拦截器。拦截器通常用于实现如登录检查、权限验证、日志记录、性能统计等跨切面的功能。 1. 拦截器的注册:拦截...
6. **ExceptionHandler(错误消息统一处理)**:在SpringBoot应用中,通过全局异常处理器(@ControllerAdvice + @ExceptionHandler)可以统一处理所有控制器层的异常,提供友好的错误提示,同时便于日志记录和问题...
通过@ControllerAdvice和@ExceptionHandler注解,可以定义全局的异常处理器,统一处理应用程序可能出现的各种异常。 总的来说,Spring MVC源码的阅读可以帮助我们理解请求处理的完整流程,以及Spring如何优雅地解耦...
在本课程"跟开涛学SpringMVC(4.6)Controller接...在学习过程中,结合"跟开涛学SpringMVC(4.6)Controller接口控制器详解(6)Java开发Java经验技巧共10页.pdf"这份资料,你将能深入理解并掌握SpringMVC的核心概念。
7. **异常处理**:Spring MVC允许通过`@ExceptionHandler`注解定义全局或特定异常的处理方法,从而提供优雅的错误页面和错误信息。 8. **模板引擎支持**:Spring MVC 4.0.3支持多种模板引擎,如JSP、FreeMarker、...
Spring MVC 提供了@ControllerAdvice 和 @ExceptionHandler 注解,允许开发者统一管理全局异常,提高代码的可维护性。 9. **第十三章:权限拦截器** "ch12-interceptor-permission.rar"专注于权限验证的拦截器实现...
Spring3 MVC支持自定义拦截器,可以通过实现`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`类来创建。拦截器可以用于执行预处理操作(如登录验证)、后处理操作等。 #### 十、全局异常处理 Spring3 ...