前言Filter是JavaWeb的三大组件之一。它与Servlet非常相似。过滤器用于拦截请求,而不是处理它们。要求。当用户请求一个Servlet时,部署在请求上的Filter将首先被执行。如果Filter为“allowed”,则继承用户请求的Servlet;如果Filter为“未释放”,则用户请求的Servlet将不会执行。.可以这样理解,当用户请求一个Servlet时,Tomcat会执行请求上注册的Filter,然后是否“释放”由Filter决定。可以理解为Filter决定是否调用Servlet!当Servlet代码执行时,Filter后面的代码也会被执行。设计模式不是技术,也不是框架。这只是对以前工作的总结。在实现某个功能时,如何降低代码之间的耦合度,如何做到高内聚低耦合,设计模式说白了就是按照一定的步骤来完成相应的功能,称为设计模式。Proxy代理是指为一个对象提供一个代理对象,由代理对象控制对原对象的引用。通俗地说,代理设计模式就是我们生活中常见的中介。主要用来解决第一个问题:监听目录下某个类中某个方法的执行情况,第二个问题:在类中某个方法执行前后动态植入代码。本文将详细介绍Filter和Proxy的具体原理和用法。1、什么是过滤器《定义:》按照我们的理解,过滤器就是过滤东西,那么这个过滤器能过滤什么呢?过滤的是请求:动态资源请求(Servlet)是程序在运行过程中,代码会发生变化,所以这种资源请求称为动态网络资源请求请求:静态资源请求(css,html,js,img,png...)程序运行时,代码不会改变的请求类型称为静态网络资源请求总结:过滤器可以拦截所有资源请求Servlet乱码问题处理3.过滤器的使用《用例:》写一个类,这个类在Filter接口中实现,并实现里面的方法publicclassHelloFilterimplementsFilter{/***在创建Filter实例时初始化该方法时执行,一般用于Filter的初始化*filterConfig:*/@Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{System.out.println("initinitializationexecuted");}/***filter拦截的方法*request:对当前请求对象*response:对当前response的封装*chain:判断是否拦截的方法**/@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{System.out.println("doFilter已经执行。...");//如果执行了这个方法,则表示允许通过,如果不执行,则不允许通过chain.doFilter(request,response);}/***Filterisdead这个方法在*/@Overridepublicvoiddestroy(){System.out.println("destoryexecuted....");}}在web.xml中配置FilterHelloFiltercom.qy.filter.HelloFilterHelloFilter/*测试总结:程序启动时执行Filter的初始化方法4.过滤器的生命周期《Lifecycle:》首先,Web容器使用时,创建Filter对象publicHelloFilter(){System.out.println("类的对象创建....");}创建完成后,调用init方法初始化Filter@Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{System.out.println("initinitializationisexecuted");}当本端有请求时,则doFilter方法此时执行@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{System.out.println("doFilterexecuted....");//如果执行到该方法,则表示允许通过如果不执行,则不允许通过//Release//chain.doFilter(request,response);}当Web容器死亡时,执行destroy方法@Overridepublicvoiddestroy(){System.out.println(“破坏Executed...");}如何在init中使用filterConfig在web.xmlHelloFiltercom.qy.filter中添加初始数据过滤。HelloFilteruserNameqianyupassword123使用filterConfig获取这个数据publicvoidinit(FilterConfigfilterConfig)throwsServletException{System.out.println("initinitializationexecuted");//获取过滤器的初始化数据StringuserName=filterConfig.getInitParameter("userName");Stringpassword=filterConfig.getInitParameter("password");//获取的所有参数的名称filterConfig.getInitParameterNames();//获取应用程序filterConfig.getServletContext();//获取Filter的名称filterConfig.getFilterName();System.out.println("获取到的数据为:"+userName+"----"+password);}过滤器被释放方法是什么?chain.doFilter(请求,响应);5.代理设计模式“解决的问题:”问题:代理设计模式解决什么问题?什么是设计模式?设计模式不是技术,也不是框架,设计模式只是对以往工作的总结,实现某个功能时如何降低代码之间的耦合度,如何做到高内聚低耦合说白了,设计模式就是按照一定的步骤完成一个相应的功能。这种设计模式,也就是所谓的设计模式代理,主要用来解决一个问题?第一种:监控目录下某个类中某个方法的执行第二种:动态植入类中某个方法执行前后的代码“静态代理:”使用静态代理的前提:要代理的类必须实现接口接口。Proxy):"前提:被代理的类也必须实现接口。动态代理的实现原理:其实就是生成接口的实现类对象,然后在接口的实现类对象中传入被代理的对象.在方法执行的时候,使用代理类的方法来执行,其实和静态代理差不多,不同的是静态代理是自己写代理类,而动态代理是自动的生成的代理类和接口的实现同上代理类的生成和实现{/***第一个参数:代理对象*第二个参数:当前要执行的方法的封装*第三个参数:执行方法要传递的参数*/@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("执行前添加的函数....");Objectresult=method.invoke(newUserDAO(),args);System.out.println("执行后添加的功能....");returnresult;}});测试userDAO.save();"cglibagent:"需求:假设一个类没有实现接口?假设我们还需要监控这个类中方法的执行情况?cglib的使用场景:如果一个类没有实现接口,我们想使用这个类的方法这种情况,可以使用cglib代理,先导入cglib包,写代理类publicclassUserDAOProxy{privateUserDAOuserDAO=null;publicUserDAOProxy(UserDAOuserDAO){this.userDAO=userDAO;}/***写一个方法返回代理类的对象*@Title:getObjProxy*@Description:TODO*@param:@return*@return:Object*@throws*/publicObjectgetObjProxy(){//这个对象是用来返回代理类对象的方法Enhancerenhancer=newEnhancer();//为代理enhancer设置parent.setSuperclass(userDAO.getClass());//设置调用Callbackenhancer.setCallback(newMethodInterceptor(){@OverridepublicObjectintercept(Objectproxy,Methodmethod,Object[]arg2,MethodProxyarg3)throwsThrowable{System.out.println("植入函数....");ObjectobjResult=method.invoke(userDAO,arg2);System.out.println("implantedfunction....1111");returnobjResult;}});//生成代理类returnenhancer.create();}}写测试类@TestpublicvoidtestCglibProxy()throwsException{//获取代理类的对象UserDAOProxy2userDAOProxy=newUserDAOProxy2(newUserDAO());//第二步:调用UserDAOProxy.userDAO=(UserDAO)userDAOProxy.getObjProxy();//Step3userDAOProxy.save();}6.基于proxy和Filter的综合案例《编码处理的问题:》原理原理:filter技术拦截所有的控制请求,在控制请求中使用动态代理设计模式,监听HttpServletRequest接口中getParameter方法的执行情况,以及getParam在执行eter的时候,我们先获取这个数据,然后判断当前请求是GET还是POST。如果是GET,先用IOS-8859-1转码,再用UTF-8重新编码。如果是POST,则直接使用request.setCharacterEncoding("UTF-8")实现字符编码处理的实现publicclassCharacterFilterimplementsFilter{@Overridepublicvoidinit(FilterConfigarg0)throwsServletException{}/***这个拦截方法*/@IOOverridepublicvoiddoFilter(ServletRequestrequest,finServletFinhalinceResponserespontion),ServletException{finalHttpServletRequestreq=(HttpServletRequest)request;finalHttpServletResponseresp=(HttpServletResponse)response;//第一步:处理返回数据的编码问题resp.setContentType("text/html;charset=utf-8");//POST解决方法req.setCharacterEncoding("UTF-8");//第二步:监听httpServletRequest中getParameter方法的执行HttpServletRequestreq1=(HttpServletRequest)Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),newClass[]{HttpServletRequest.class},newInvocationHandler(){@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{//监控当前执行methodgetParameterStringmethodName=method.getName();if("getParameter".equals(methodName)){//说明执行的是getParameter//判断当前执行的是POST?还是得到?StringreqName=req.getMethod();//通过key获取这个值Stringval=(String)method.invoke(req,args);if("GET".equalsIgnoreCase(reqName)){//说明是GET方法//执行thismethodtogetthisvalueval=newString(val.getBytes("ISO-8859-1"),"UTF-8");}elseif("POST".equalsIgnoreCase(reqName)){//说明是POST方法}//返回该方法的结果returnval;}else{returnmethod.invoke(req,args);}}});//最终释放chain.doFilter(req1,resp);}@Overridepublicvoiddestroy(){}}"性格和谐问题:》我理解一个问题:什么是性格和谐:类似于博客网站,比如你发表不文明的言论,不会直接显示,而是会显示为***等。这种现象叫做为了字符和谐要实现字符和谐,首先要解决编码问题(上面已经解决了)在过滤器中设置脏数据//需要和谐的脏数据privateString[]dirtyData={"MMD","NND","GD","CTM"};字符编码问题处理时协调(编码处理后调用)protectedStringhandleDirtyData(Stringval){for(inti=0;i