SpringMVC的过滤器和拦截器

279 阅读3分钟

f5445e46a336c9969d5ede7d3f2be60c_800_340.jpg

狂风暴雪之中,我有孤独和烈酒。无边的冰层,我必勇往直前。SpringMVC的一些其他介绍,欢迎讨论❤️

过滤器Filter

  • 可以拦截所有的请求
  • 新建一个class 实现filter接口
@Override
public void doFilter(ServletRequest servletReguest, ServletResponse servletResponse, 
FilterChain filterChain) throws IOException, ServletException {

    System.out.println("doFilter");
    //获得用户请求的URI
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    HttpSession session = request.getSession();
    String noLoginPaths = config.getInitParameter("aa"); 
    
    //已获filterconfig对象,可以获其中属性
    System.out.printIn(noLoginPaths);
    
    //获得用户请求的URI
    String path = request .getRequestURI();
    String contextPath = request .getContextPath();
    System.out.println(path);
    if(path.endswith("login.jsp")){
        filterChain.doFilter(servletReguest, servletResponse);
        return;
    }

    String user = (string) session.getAttribute("user");
    if (user == null) {
       response.sendRedirect(contextPath+"/login.jsp");
       return;
    }
    filterChain.doFilter(servletRequest, servletResponse);
    
  • ajax中发送put请求的时候,tomcat不会将请求值封装成一个map,所以用request.getparameter();方法就获取不到任何的请求值。
  • 解决办法是配置HttpPutFormContentFilter拦截器。它会将request中的请求值封装成一个map,并且request被重新包装,所以request.getparameter()既可以获取到值了。

重定向的传值问题

  • SpringMvc通过 return "redirect:/webpage/NewFile2.jsp"这种方式返回值时是通过重定向的方式返回的页面,此时客户端的url会改变。怎么带值呢?
  • 可以使用RedirectAttributesaddFlashAttribute(key,value)方法 将值传到jsp页面,同时 需要在放置值的时候将session中的值remove(以便显示的时候是最新的值)。session.removeAttribute("org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS");
  • 在jsp目标页面通过el表达式取出: ${sessionScope['org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS'][0][key]}
@RequestMapping(value="/textRedirectAttributes",method=RequestMethod.POST)
public String textRedirectAttributes(@RequestParam(value="name",required=false)String name, 
        RedirectAttributes redirectAttributes, HttpSession session){
        
        session.removeAttribute("org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS");
        redirectAttributes.addFlashAttribute("name", name);
    
        return "redirect:/webpage/File2.jsp"
}

拦截器

  • SpringMVC也可以使用拦截器对请求进行拦截处理,
  • preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
  • postHandle(): 这个方法在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理
  • afterCompletion() : 这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

自定义拦截器

  • 新建一个class 实现 HandlerInterceptor接口。
//其中的preHandle方法是在请求的目标方法之前被调用,返回false,下面的拦截器也不会被调用,目标方法不会执行。
//返回true,则会一路畅通,继续调用后续的拦截器,目标方法也会执行
public class MyHandlerInterceptor implements HandlerInterceptor {

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

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}
  • springMvc配置文件中配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
    <bean id="myHandlerInterceptor" class="com.xxx.MyHandlerInterceptor"></bean>
</mvc:interceptors>
  • 拦截器可以拦截特定请求
<!-- 配置拦截器,只作用于/textInterceptor请求的目标方法。 -->
<mvc:interceptors>
<mvc:interceptor>
    <mvc:mapping path="/textInterceptor"/>
    <bean id="myHandlerInterceptor'class="com.xxx.MyHandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
    <mvc:exclude-mapping path="/textValidateMethod"/>
    <bean id="myHandlerInterceptor" class="com.xxx.MyHandlerInterceptor"></bean></mvc:interceptor>
</mvc:interceptors>
  • 拦截器的执行顺序:
    • preHandle 是按配置的拦截器的正序执行
    • postHandle是按配置的拦截器的倒序执行
    • aftercompletion是按配置的拦截器的倒序执行