文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

组件必知必会|那些年我们使用过的轮子—Filter和Proxy

2024-12-03 16:54

关注

 前言

过滤器Filter是JavaWeb三大组件之一,它与Servlet很相似,过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter“不放行”,那么就不会执行用户请求的Servlet。可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。

设计模式不是技术,也不是什么框架,只是前人的一个工作的总结,在实现某一个功能的时候,怎样来减少代码之间的耦合性,以及如何实现高内聚低耦合,设计模式说白了就是按照一定的步骤来完成相应的一个功能,这个就称为设计模式。代理Proxy是指给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗来讲,代理设计模式就是我们生活中常见的中介。主要用来解决的问题第一个:监控目录一个类里面的方法的执行,第二个:在类里面某一个方法执行的前后动态的植入代码。

本文将带大家详细介绍Filter以及Proxy的具体原理以及使用。

1、什么是过滤器

「定义:」

2、过滤器的作用

「主要用途:」

3、过滤器的使用

「使用案例:」

编写一个类,这个类实现于Filter接口,并实现里面的方法

  1. public class HelloFilter implements Filter{ 
  2.   
  3.  @Override 
  4.  public void init(FilterConfig filterConfig) throws ServletException { 
  5.   System.out.println("init初始化执行了"); 
  6.  } 
  7.      
  8.  @Override 
  9.  public void doFilter(ServletRequest request, ServletResponse response, 
  10.    FilterChain chain) throws IOException, ServletException { 
  11.   System.out.println("doFilter执行了...."); 
  12.   //执行了这个方法那么就表示允许通过  没有执行那么就不允许通过 
  13.   chain.doFilter(request, response); 
  14.    
  15.  } 
  16.   
  17.      
  18.  @Override 
  19.  public void destroy() { 
  20.    
  21.   System.out.println("destory执行了...."); 
  22.  } 

在web.xml中配置Filter

  1.  
  2.     name>HelloFiltername
  3.     com.qy.filter.HelloFilter 
  4.    
  5.   
  6.     name>HelloFiltername
  7.      
  8.            @Override 
  9.      public Object invoke(Object proxy, Method method, Object[] args) 
  10.        throws Throwable { 
  11.            System.out.println("执行前添加的功能...."); 
  12.            Object result=method.invoke(new UserDAO(), args); 
  13.            System.out.println("执行后添加的功能...."); 
  14.       return result; 
  15.      } 
  16.     }); 

测试

  1. userDAO.save(); 

「cglib代理:」

  1. cglib的使用场景:就是一个类如果没有实现接口  而且我们想在这个类的方法里面动态植入代码 那么这种情况下就可以使用cglib代理 
  1. public class UserDAOProxy { 
  2.  private UserDAO userDAO=null
  3.  public UserDAOProxy(UserDAO userDAO) { 
  4.   this.userDAO=userDAO; 
  5.  } 
  6.  
  7.   
  8.  public Object getObjProxy(){ 
  9.   //这个对象就是用来返回代理类对象的方法 
  10.   Enhancer enhancer=new Enhancer(); 
  11.   //给代理了设置父亲 
  12.  enhancer.setSuperclass(userDAO.getClass()); 
  13.   //设置调用的回调 
  14.   enhancer.setCallback(new MethodInterceptor() { 
  15.    @Override 
  16.    public Object intercept(Object proxy, Method method, Object[] arg2, 
  17.      MethodProxy arg3) throws Throwable { 
  18.     System.out.println("植入了功能...."); 
  19.     Object objResult=method.invoke(userDAO, arg2); 
  20.     System.out.println("植入了功能....1111"); 
  21.     return objResult; 
  22.    } 
  23.   }); 
  24.   //生成代理类 
  25.   return enhancer.create(); 
  26.  } 

编写测试类

  1. @Test 
  2.    public void testCglibProxy() throws Exception { 
  3.    
  4.   //获取代理类的对象 
  5.   UserDAOProxy2 userDAOProxy=new UserDAOProxy2(new UserDAO()); 
  6.   //第二步:调用 
  7.   UserDAO userDAO=(UserDAO) userDAOProxy.getObjProxy(); 
  8.   //第三步 
  9.   userDAO.save(); 
  10.    } 

6、基于代理和Filter的综合案例

「编码处理的问题:」

原理

  1. 原理:过滤器技术拦截所有的controll的请求、在controll请求中使用了动态代理的设计模式监听了HttpServletRequest这个接口中getParameter方法的执行、在getParameter执行的时候、我们首先去获取这个数据、再通过判断当前的请求是GET还是POST、如果是GET那么先使用IOS-8859-1进行转码 然后使用UTF-8从新进行编码、如果是POST那么直接使用request.setCharacterEncoding(“UTF-8”)来进行处理 

字符编码处理的实现

  1.  public class CharacterFilter implements Filter{ 
  2.  @Override 
  3.  public void init(FilterConfig arg0) throws ServletException { 
  4.    
  5.  }   
  6.      
  7.  @Override 
  8.  public void doFilter(ServletRequest request, ServletResponse response, 
  9.    final FilterChain chain) throws IOException, ServletException { 
  10.        
  11.       final HttpServletRequest req=(HttpServletRequest) request; 
  12.       final HttpServletResponse resp=(HttpServletResponse) response; 
  13.        
  14.       //第一步:将返回数据的编码问题给处理了 
  15.       resp.setContentType("text/html;charset=utf-8"); 
  16.       //POST的解决方案  
  17.       req.setCharacterEncoding("UTF-8"); 
  18.       //第二步:监听httpServletRequest中 getParameter方法的执行 
  19.       HttpServletRequest req1= (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(), 
  20.         new Class[]{HttpServletRequest.class}, 
  21.         new InvocationHandler() { 
  22.       @Override 
  23.       public Object invoke(Object proxy, Method method, Object[] args) 
  24.         throws Throwable { 
  25.           //监听当前执行的方法是不是 getParameter 
  26.           String methodName=method.getName(); 
  27.           if("getParameter".equals(methodName)){ //说明执行的是getParameter 
  28.           //判断当前执行的是POST呢?还是GET呢? 
  29.           String reqName=req.getMethod(); 
  30.            
  31.           //通过key获取这个值 
  32.           String val= (String) method.invoke(req, args); 
  33.           if("GET".equalsIgnoreCase(reqName)){ //说明是GET方法 
  34.            //执行这个方法获取这个值 
  35.            val=new String(val.getBytes("ISO-8859-1"),"UTF-8"); 
  36.             
  37.           }else if("POST".equalsIgnoreCase(reqName)){ //说明是POST方法 
  38.             
  39.           } 
  40.           //返回这个方法执行的结果 
  41.           return val;  
  42.           }else
  43.           return  method.invoke(req, args); 
  44.           } 
  45.          } 
  46.      }); 
  47.     
  48.      //最终要进行放行 
  49.      chain.doFilter(req1, resp); 
  50.  } 
  51.  @Override 
  52.  public void destroy() {  
  53.    
  54.  } 

「字符和谐的问题:」

  1. //需要和谐的脏数据 
  2.  private String[] dirtyData={"MMD","NND","GD","CTM"}; 

在处理完字符编码问题的时候进行和谐(在处理完编码之后进行调用)

  1. protected String handleDirtyData(String val) { 
  2.   for (int i = 0; i < dirtyData.length; i++) { 
  3.    if(val.contains(dirtyData[i])){ 
  4.     val=val.replaceAll(dirtyData[i],"***"); 
  5.    } 
  6.   } 
  7.   return val; 
  8.  } 

测试

结语

本篇关于过滤器Filter及代理Proxy的介绍就先到这里结束了,后续会出更多关于Filter和代理Proxy系列更多文章,谢谢大家支持!

 

来源:浅羽的IT小屋内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯