今天小编将给大家分享拦截器与全局异常
SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 controller生命周期之内可以多次调用。
过滤器:
拦截器:
1)日志记录
2)权限检查
3)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。



关于拦截器接口中定义的方法的说明:
登录验证, 开发步骤:
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <html>
- <head>
- <title>Titletitle>
- head>
- <body>
- <c:if test="${not empty error}">
- <div>
- ${error}
- div>
- c:if>
- <form action="<%=request.getContextPath()%>/user/login" method="post">
- 用户名: <input type="text" name="name"> <br data-tomark-pass> 密码: <input type="password" name="password"><br data-tomark-pass> <input type="submit" value="提交">
- form>
- body>
- html>
- @Controller
- public class LoginController {
-
- @RequestMapping("/")
- public String loginPage() {
- return "login";
- }
-
- @PostMapping("/user/login")
- public String login(String name, String password, HttpSession session, Model model) {
-
- if("admin".equals(name) && "123".equals(password)) {
- session.setAttribute("user", name);
- return "index";
- }
- model.addAttribute("error", "用户名或密码错误");
- return "login";
- }
-
- @GetMapping("/user/logout")
- public String logout(HttpSession session) {
- session.removeAttribute("user");
- return "redirect:/";
- }
- }
<a href="<%=request.getContextPath()%>/user/logout">退出a>
测试可以登录后,可以进行拦截器的编写了
- public class LoginInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
- String uri = request.getRequestURI();
- String contextPath = request.getContextPath();
-
- //登录页面,放行
- if (uri.endsWith(contextPath+"/") || uri.indexOf("/user/login") > 0) {
- return true;
- }
-
- //其他情况需要验证登录
- HttpSession session = request.getSession();
- Object user = session.getAttribute("user");
-
- //已登录,放行
- if (Objects.nonNull(user)) {
- return true;
- }
-
- session.setAttribute("error", "请先登录");
- //request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
- response.sendRedirect(contextPath+"/");
-
- //不再处理其他拦截器,直接返回
- return false;
- }
-
- }
因为我们可以把service,dao,contrller里面包含全部有可能出现的异常交给全局异常一起处理,然后返回给异常error.jsp页面

SpringMVC中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口
-
- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
-
- <property name="defaultErrorView" value="error"/>
-
- <property name="exceptionAttribute" value="ex"/>
-
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.RuntimeException">errorprop>
- props>
-
- property>
- bean>
2)配置错误页面
在WEB-INF/jsp 目录下,创建error.jsp, 与上面的spring-mvc.xml中的配置相对应
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>Titletitle>
- head>
- <body>
- <h1>系统异常,请与管理员联系h1>
- body>
- html>
通过实现异常处理处理接口HandlerExceptionResovler处理全局异常。
1) 实现接口
- @Component
- public class GlobalException implements HandlerExceptionResolver {
-
- @Override
- public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
-
- ModelAndView mv = new ModelAndView();
- mv.setViewName("error");
- if(ex instanceof RuntimeException) {
- mv.addObject("msg", ex.getMessage());
- }
- if(ex instanceof Exception){
- 编辑其他异常
- }
- return mv;
- }
- }
定义全局异常处理器:
- @ControllerAdvice
- public class HandlerGlobalException {
-
- @ExceptionHandler
- public ModelAndView handler(Exception ex) {
-
- ModelAndView mv = new ModelAndView();
- if(ex instanceof RuntimeException) {
- mv.addObject("msg", ex.getMessage());
- }
- mv.setViewName("error");
-
- //如果系统直接返回JSON格式的错误数据,可以如下操作
- //mv.setView(new MappingJackson2JsonView());
-
- return mv;
- }
-
- }