SpringMVC拦截器 和servlet过滤器 的使用

您所在的位置:网站首页 拦截器和过滤器的区别 SpringMVC拦截器 和servlet过滤器 的使用

SpringMVC拦截器 和servlet过滤器 的使用

2024-06-27 00:51| 来源: 网络整理| 查看: 265

servlet过滤器

1.什么是过滤器

过滤器实际上就是对web资源进⾏拦截,做⼀些处理后再交给下⼀个过滤器或servlet处理,通常都 是⽤来拦截request进⾏处理的,也可以对返回的response进⾏拦截处理,可以同时设置多个过滤器。过滤器依赖于servlet,一个过滤器可以加在多个servlet上,(多个过滤器也可以加在一个servlet上)

2.过滤器的语法格式

实现Javax.serlvet.Filter接口,重写里面的方法(对应servlet-api.jar)

package util; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class FirstFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("初始化filter");//当服务器启动时执行init } @Override //请求和响应时都会执行这个方法 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("过滤器开始"); //调取下一个过滤器,或者调取servlet filterChain.doFilter(servletRequest, servletResponse); System.out.println("过滤器结束"); } @Override public void destroy() { System.out.println("销毁filter"); } } 3.在web.xml⽂件中配置 过滤器名称 过滤器所在的路径 过滤器名称 需要过滤的资源

示例:

f1 util.FirstFilter f1 /* 4.使⽤场景

1.如何防⽌⽤户未登录就执⾏后续操作

String name=(String)session.getAttribute("key");

if(name==null){ //跳转到登录⻚⾯ }

.2.设置编码⽅式--统⼀设置编码

3.加密解密(密码的加密和解密)

4.⾮法⽂字筛选

5.下载资源的限制 过滤器的特点:在servlet之前和之后都会被执⾏

5.过滤器中的url-pattern中的 / 和 /*  和/login testFilter1 /*

会过滤所有请求,包括对静态资源的访问,都会进入过滤器。

会匹配所有的url:路径型的和后缀型的url(包括/springmvc,.jsp,.js和*.html等)。 这种形式将会覆盖所有其它的servlet。不管你发出了什么样的请求,最终都会在这个servlet中结束。因此,对于servlet来说,这是一个很糟糕的URL模式。通常来讲,你只会想要在一个Filter中使用这种模式。

testFilter1 /

会匹配到/springmvc这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url。

这时如果有静态资源的访问,要再处理对静态资源的访问不到的问题。 

testFilter2 /login

只会过滤/login访问路径

例子:验证用户登录 过滤器 package util; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class FirstFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("初始化filter");//当服务器启动时执行init } @Override //请求和响应时都会执行这个方法 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("过滤器开始"); //处理乱码 HttpServletRequest request=(HttpServletRequest)servletRequest; HttpServletResponse response=(HttpServletResponse)servletResponse; request.setCharacterEncoding("utf-8"); //防止用户在未登录的情况下访问资源 String requestURI = request.getRequestURI();//获得请求地址 System.out.println("requestURI="+requestURI); Object username = request.getSession().getAttribute("username"); if(requestURI.endsWith("testsession.jsp")&&username==null){ response.sendRedirect("index.jsp"); } //调取下一个过滤器,或者调取servlet filterChain.doFilter(servletRequest, servletResponse); System.out.println("过滤器结束"); } @Override public void destroy() { System.out.println("销毁filter"); } } 后端 package servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet(urlPatterns = "/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("error.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("login-servlet被执行"); //1.接收参数 String username = req.getParameter("username"); String pass = req.getParameter("pass"); //2.判断正误 if("admin".equals(username)&&"123456".equals(pass)){ //登录成功 //session存值 HttpSession session = req.getSession(); session.setAttribute("username",username); session.setAttribute("password",pass); session.setMaxInactiveInterval(60*30);//单位是秒 //重定向或者转发时,session数据是不会丢失的,重定向时,request中的数据会丢失 resp.sendRedirect("success.jsp"); }else{ //登录失败 //1.后台创建cookie Cookie cookie = new Cookie("uname",username); //2.返回给前端 resp.addCookie(cookie); resp.sendRedirect("index.jsp"); } } } 前端 $Title$ 0){ for (Cookie cookie : cookies) { if(cookie.getName().equals("uname")){ value = cookie.getValue(); break; } } } pageContext.setAttribute("unamecookie",value); %> 登录 用户名: 密码: SpringMVC 中的 拦截器 1.概念

java中的拦截器是动态拦截action调用的对象。依赖于web框架,在springmvc中依赖于SpringMVC框架,在实现上基于Java的反射机制,属于AOP的一种应用,作用类似于过滤器,但是拦截器只能对Controller请求进行拦截,对其他的直接访问静态资源的请求无法拦截处理。  

拦截器( Interceptor)是非常重要的,它的主要作用是拦截指定的用户请求,并进行 相应的预处理与后处理。

2.拦截时间

拦截的时间点在“处理器映射器HandlerMapping根据用户提交的请求映射出了所要执行的处理器类,并 且也找到了要执行该处理器类的处理器适配器,在处理器适配器HandlerAdaptor执行处理器之前”。

在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链 HandlerExecutionChain,并返回给了前端控制器。

3.实现拦截器

自定义拦截器,需要实现 HandlerInterceptor 接口。而该接口中含有三个方法:

public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } } 4.拦截器方法说明

preHandle(request,response, Object handler):

该方法在处理器方法执行之前执行。其返回值为boolean,若为true,则紧接着会执行处理器方法,且 会将afterCompletion()方法放入到一个专门的方法栈中等待执行。 postHandle(request,response, Object handler,modelAndView):

该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处 理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果 数据,且可以修改跳转方向。

afterCompletion(request,response, Object handler, Exception ex): 当 preHandle()方法返回true时,会将该方法放到专门的方法栈中,等到对请求进行响应的所工作完 成之后才执行该方法。即该方法是在前端控制器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView再操作也对响应无济于事。

afterCompletion最后执行的方法,清除资源,例如在Controller方法中加入数据

5.方法使用场景 import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { //执行时间: 控制器方法执行之前,在ModelAndView返回之前 //使用场景: 登录验证 // 返回值 true : 继续执行控制器方法 表示放行 false: 不会继续执行控制器方法,表示拦截 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle-------------------"); return true; } //执行时间: 控制器方法执行之hou后,在ModelAndView返回之前,有机会修改返回值 //使用场景: 日记记录,记录登录的ip,时间 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle-------------------"); } //执行时间: 控制器方法执行之后,在ModelAndView返回之后,没有机会修改返回值 //使用场景: 全局资源的一些操作 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion-------------------"); } 6.设置多个拦截器所执行的顺序

(默认对三种方法都实现 )

preHandle1->  preHandle2  ->postHande2  ->perHande2 ->afterCompletion2 ->afterCompletion1

测试

上传的文件是否符合定义的格式,不符合的进行拦截

环境搭建      

1.需要在maven 的pom.xml中引入 的依赖和 插件   org.springframework spring-webmvc 5.2.13.RELEASE javax.servlet javax.servlet-api 4.0.1 provided org.apache.maven.plugins maven-compiler-plugin 3.8.0 1.8 1.8 org.apache.tomcat.maven tomcat7-maven-plugin 2.2 / 8080 2.springMVC 的xml文件中拦截路径的配置   拦截关键字路径

当使用/user/xxx拦截时候

这时又多了一个需求就是拦截   /user/manager/xxxx

如何对含有关键字manger路径进行拦截

manger前面如果只有一层路径  使用/*/manger/**    例如  user/manger/xxxx

manger前面含义多层路径  使用    /**/manger/**      此时前面如果没有  路径 由于/**资源通配符的作用,过滤也起作用

如何放行特定的请求路径 

使用

3.实现类 package com.kkb.interceptor; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Iterator; import java.util.Map public class FileInterceptor implements HandlerInterceptor { /** * 在文件上传之前判断文件后缀是否合法 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //判断是否是文件上传的请求 boolean flag=true; if(request instanceof MultipartHttpServletRequest){ //单一上传文件 method="post" enctype="multipart/form-data" MultipartHttpServletRequest multipartRequest= (MultipartHttpServletRequest) request; Map fileMap = multipartRequest.getFileMap(); //遍历文件 //通过entrySet // Set entries = fileMap.entrySet(); // for (Map.Entry entry : entries) { // System.out.println("key:"+entry.getKey()+" " // +"value:"+entry.getValue()); // } Iterator iterator = fileMap.keySet().iterator(); while(iterator.hasNext()){ String key = iterator.next(); MultipartFile file = multipartRequest.getFile(key); String originalFilename = file.getOriginalFilename(); String hz = originalFilename.substring(originalFilename.lastIndexOf(".")); //判断后缀是否合法 if(!hz.toLowerCase().equals(".png") && !hz.toLowerCase().equals(".jpg")){ request.getRequestDispatcher("/jsp/fileTypError.jsp").forward(request,response); flag=false; } } } return flag; } 拦截器实现验证登录

1.aa 

2.bb

过滤器和拦截器的区别:

1 、拦截器是基于java的反射机制的,而过滤器是基于函数回调。

2 、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

3 、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

4 、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

5 、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

参考:java中过滤器和拦截器的区别



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3