实验8 Servlet过滤器与监听器
- 格式:doc
- 大小:237.50 KB
- 文档页数:10
详解Servlet之过滤器(Filter)过滤器1.为什么使⽤它?有很多全站性的东西需要处理,例如乱码问题,通过过滤器统⼀进⾏过滤更简单2.有什么⽤?实现⽤户在访问某个⽬标资源之前,对访问的请求和响应进⾏拦截。
简单说,就是可以实现web容器对某资源的访问前截获进⾏相关的处理,还可以在某资源向web容器返回响应前进⾏截获进⾏处理。
3.怎么⽤?步骤1:先写⼀个类实现javax.servlet.Filter接⼝步骤2:重写抽象⽅法步骤3:在doFilter()⽅法中写处理代码,最后⽤FilterChain调⽤FilterChain.doFilter(req, resp)⽅法,表⽰可以执⾏后⾯的拦截器(如果有的话)步骤3:进⾏配置,web.xml配置如下<!-- 优先配置过滤器 ,过滤器应该在Servlet前⾯配置,并且过滤器之间有顺序 --><filter><filter-name>firstfilter</filter-name><filter-class>cn.hk.filter.FirstFilter</filter-class></filter><filter-mapping><filter-name>firstfilter</filter-name><!-- 拦截访问资源*表⽰拦截所以资源--><url-pattern>/*</url-pattern></filter-mapping>4运⽤的场景?1)实现URL级别的权限访问控制;2)处理全站中⽂乱码问题;3)实现⾃动登录;4)过滤敏感词汇;5)压缩⽹页;6)选择性让浏览器缓存;等等。
这⼏种功能的实现采⽤同样的原理,那就是使⽤包装模式或动态代理增强request或response对象的功能。
Servlet进阶API、过滤器与监听器1、Servlet进阶API每个Servlet都必须由web容器读取Servlet设置信息(无论使用标注还是web.xml)、初始化等,才可以真正成为一个Servlet。
对于每个Servlet的设置信息,web容器会为其生成一个ServletConfig作为代表对象,你可以从该对象取得Servlet初始参数,以及代表整个web应用程序的ServletContext对象。
1.Servlet、ServletConfig与GenericServlet在Servlet接口上,定义了与Servlet生命周期及请求服务相关的init()、service()与destroy()三个方法。
每一次请求来到容器时,会产生HttpServletResponse与HttpServletResponse对象,并在调用service()方法时当作参数传入。
在Web容器启动后,会读取Servlet设置信息,将Servlet类加载并实例化,并为每个Servlet设置信息产生一个Servletconfig对象,而后调用Servlet接口的init()方法并将发生的ServletConfig对象当作参数传入。
这个过程只会在创建Servlet实例后发生一次。
ServletConfig即每个Servlet设置的代表对象,容器会为每个Servlet设置信息产生一个Servlet及ServletConfig实例。
GenericServlet同时实现了Servlet及Servlet-Config。
GenericServlet主要的目的,就是将初始Servlet调用init()方法传入的ServletConfig封装起来:private transient ServletConfig config;public void init(SetvletConfig config)throws ServletException{this,config = config;this.init();}public void init()throws ServletException{}GenericServlet在实现Servlet的init()方法时,也调用了另一个无参数的init()方法,在编写Servlet时,如果有一些初始时所要运行的动作,可以重新定义这个无参数的init()方法,而不是直接重新定义有ServletConfig参数的init()方法。
案例1:统一设置字符集案例2:拦截URL,不登录不允许直接访问页面监听器监听器顾名思义就是监听某种事件的发生,即当某个事件发生时,就触发了某个设置好的监听器,但是这里触发的原因不同。
例如地震监测仪器监听地震的发生,大气监测仪,监测空气的变化以提供预警。
在servlet中因监听对象的不同也分为不同的监听器,这里指的监听对象是application、session对象,每种对象有各自的监听器。
1.application监听器:ServletContextListener需要实现的方法:(1)public void contextInitialized(ServletContextEvent e); //在application创建时就调用(2)public void contextDestroyed(ServletContextEvent e); //当application销毁时调用ServletContextEvent的getServletContext()方法可以取得application对象;创建完成监听器后需要在web.xml中做如下配置标签是单独出现的包含一个子标签,指定了监听类的全称(包名+类名)2.application属性监听器:ServletContextAttributeListener需要实现的方法:(1)public void attributeAdded(ServletContextAttributeEvent e); //当调用application.setAttribute()时调用(2)public void attributeRemoved(ServletContextAttributeEvent e); //当调用applcaition.removeAttribute()时调用(3)public void attributeReplaced(ServletContextAttributeEvent e); //当调用两次application.setAttribute()赋予相同属性时调用参数ServletContextAttributeEvent可以获得触发该监听器的属性名称和属性值,方法有:(1)getName(); 取得属性的名称;(2)getValue(); 取得属性的值;(注意:返回的是Object,必须转型)3.session监听器:HttpSessionListener需要实现的方法:(1)public void sessionCreated(HttpSessionEvent e); //当打开一个浏览器时,就会触发这个方法;(2)public void sessionDestroyed(HttpSessionEvent e); //当调用session.invalidate();或超时时调用HttpSessionEvent的方法getSession()获得触发监听器的session对象;销毁session常用的有2种方式:(1)session.invalidate();//直接销毁(2)在web.xml中设置超时时间://所有session起作用<session-config><session-timeout>5</session-timeout><!-- 5分钟 --></session-config>注意:如果会话超时时间设置为-1,则表示会话永远不会超时;4.session属性监听器:HttpSessionAttributeListener需要实现的方法:(1)public void attributeAdded(HttpSessionBindingEvent e); //当调用session.setAttribute()时调用(2)public void attributeRemoved(HttpSessionBindingEvent e); //当调用session.removeAttribute()时调用(3)public void attributeReplaced(HttpSessionBindingEvent e); //当调用两次session.setAttribute()赋予相同属性时调用HttpSessionBindingEvent 方法:(1)getSession();//获取触发监听器的session(2)getName();//获取属性名称(3)getValue();//获取属性值监听器应用场景 ServletContextListener:在任何Servlet提供服务之前执行、在Servlet销毁时执行,用于提前初始化一些资源,比如数据库连接、销毁一些资源,比如数据库连接;ServletContextAttributeListener:上下文中添加、删除、替换了属性;HttpSessionListener:多少个在线用户,即跟踪会话;HttpSessionAttributeListener:会话属性添加、删除、替换;综合案例:做一个网站在线人数统计,可以通过ServletContextListener监听,当Web应用上下文启动时,在ServletContext中添加一个List.用来准备存放在线的用户名,然后通过HttpSessionAttributeListener监听,当用户登录成功,把用户名设置到Session中。
聊聊java过滤器、监听器、拦截器的区别(终结篇)过滤器、监听器、拦截器概念概念1、servlet:servlet是⼀种运⾏服务器端的java应⽤程序,具有独⽴于平台和协议的特性,可以动态⽣成web页⾯它⼯作在客户端请求与服务器响应的中间层;2、filter:filter是⼀个可以复⽤的代码⽚段,可以⽤来转换HTTP请求,响应和头信息。
它不能产⽣⼀个请求或者响应,它只是修改对某⼀资源的请求或者响应;3、listener:监听器,通过listener可以坚挺web服务器中某⼀执⾏动作,并根据其要求作出相应的响应。
就是在application,session,request三个对象创建消亡或者往其中添加修改删除属性时⾃动执⾏代码的功能组件;4、interceptor:拦截器是对过滤器更加细化的应⽤,他不仅可以应⽤在service⽅法前后还可以应⽤到其他⽅法的前后拦截器;5、servlet,filter,listener是配置到web.xml中,interceptor不配置到web.xml中,struts的拦截器配置到struts。
xml中。
spring的拦截器配置到spring.xml中;过滤器和拦截器的区别先说最易混淆的过滤器和拦截器的区别:1、拦截器是基于java的反射机制的,⽽过滤器是基于函数回调。
2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3、拦截器只能对action请求起作⽤,⽽过滤器则可以对⼏乎所有的请求起作⽤。
4、拦截器可以访问action上下⽂、值栈⾥的对象,⽽过滤器不能访问。
5、在action的⽣命周期中,拦截器可以多次被调⽤,⽽过滤器只能在容器初始化时被调⽤⼀次。
6、拦截器可以获取IOC容器中的各个bean,⽽过滤器就不⾏,这点很重要,在拦截器⾥注⼊⼀个service,可以调⽤业务逻辑。
过滤器、监听器、拦截器的⽣命周期1、servletservle的⽣命周期开始于被装⼊web服务器的内存中,并在web服务终⽌或者重新装⼊servlet的时候结束;servlet⼀旦被装⼊web服务器,⼀般不会从web服务器内存中删除;直到web服务器关闭;装⼊:启动服务器时加载servlet的实例;初始化:web服务器接收到请求时,或者两者之间的某个时刻启动,调⽤init()调⽤:从第⼀次到以后的多次访问,都只调⽤doGet()或dopost)()⽅法;销毁;停⽌服务器时调⽤destroy()⽅法,销毁实例;2、filter需要实现javax.servlet包的Filter接⼝的三个⽅法init(),doFilter(),destroy();加载:启动服务器时加载过滤器的实例,并调⽤init()⽅法;调⽤:每次请求的时候只调⽤⽅法doFilter()进⾏处理;销毁:服务器关闭前调⽤destroy()⽅法,销毁实例;3、listenerweb.xml的加载顺序是:context-param->listener->filter->servlet4、interceptor加载配置⽂件后初始化拦截器,当有对action的请求的时候,调⽤interceptor⽅法,最后也是根据服务器停⽌进⾏销毁;过滤器、监听器、拦截器的职责1、servlet创建并返回⼀个包含基于客户请求性质的动态内容的完整的html页⾯创建可嵌⼊到现有的html页⾯中的⼀部分html页⾯(html⽚段)读取客户端发来的隐藏数据读取客户端发来的显⽰数据与其他服务器资源(包括数据库和java的应⽤程序)进⾏通信2、filterfilter能够在⼀个请求到达servlet之前预处理⽤户请求,也可以在离开servlet时处理http响应:在执⾏servlet之前,⾸先执⾏filter程序,并为之做⼀些预处理⼯作;在servlet被调⽤之后截获servlet的执⾏3、listenerservlet2.4规范提供了8个listener接⼝,可以将其分为三类,分别如下;第⼀类:与HttpContext有关的listener接⼝,包括:ServletContextListener、ServletContextAttributeListener第⼆类:与HttpSession有关的listner接⼝。
实验8 Servlet过滤器与监听器第一部分 Servlet过滤器一、实验目的1. 了解过滤器的作用;2. 掌握过滤器的开发与部署的步骤;3. 了解过滤器链。
二、实验原理过滤器是web服务器上的组件,它们对客户和资源之间的请求和响应进行过滤。
过滤器的工作原理是:当servlet容器接收到对某个资源的请求,它要检查是否有过滤器与之关联。
如果有过滤器与该资源关联,servlet容器将把该请求发送给过滤器。
在过滤器处理完请求后,它将做下面3件事:∙产生响应并将其返回给客户;∙如果有过滤器链,它将把(修改过或没有修改过)请求传递给下一个过滤器;∙将请求传递给不同的资源。
当请求返回到客户时,它是以相反的方向经过同一组过滤器返回。
过滤器链中的每个过滤器够可能修改响应。
过滤器API主要包括:Filter、FilterConfig和FilterChain接口。
三、实验内容与步骤(一)编写一个过滤器审计用户对资源的访问。
【步骤1】该过滤器实现的功能是,当用户访问应用程序任何资源时,将用户的IP地址和主机名写入日志文件中,过滤器代码如下:package filter;import java.io.IOException;import javax.servlet.*;import javax.servlet.http.*;public class AuditFilter implements Filter {protected FilterConfig config;public void init(FilterConfig filterConfig)throws ServletException {this.config = filterConfig;}public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;String addr = req.getRemoteAddr();String user = req.getRemoteHost();config.getServletContext().log("RemoteAddress:"+addr+",RemoteHost:"+user);chain.doFilter(req, res);}public void destroy() {}}【步骤2】配置过滤器。
在部署描述文件web.xml中配置过滤器:<filter><filter-name>AuditFilter</filter-name><filter-class>filter. AuditFilter</filter-class></filter><filter-mapping><filter-name>AuditFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>上述代码中过滤器映射使用的URL模式为/*,这表示将该过滤器映射到Web应用程序的任何资源。
如果只对某些资源(如JSP页面审计,则可以指定具体的资源)。
【步骤3】访问该应用程序中的任何一个资源,如使用下面的URL访问onlineCount.jsp:http://localhost:8080/ helloapp/onlineCount.jsp然后打开<CATALINA_HOME>\logs目录中的localhost.2006-02-05.log文件中有下面一行(访问多个资源就会有多行):信息: RemoteAddress:127.0.0.1,RemoteHost:127.0.0.1新建一个jsp文件MyJsp1.jsp 在旧的jsp里输入:<body>This is my JSP page. <br><a href="MyJsp1.jsp">send</a></body>(二)编写一个过滤器改变请求编码。
【步骤1】编写一个loginform.html文件,代码如下:<html><head><title>使用过滤器改变请求编码</title><meta http-equiv="Content-Type" content="text/html;charset=GB2312"></head><body><center><h2>请输入用户名和口令:</h2><form method="post" action="servlet/check"><table><tr><td>用户名:</td><td><input name="name" type="text"></td></tr><tr><td>口令:</td><td><input name="pass" type="password"></td></tr><tr><td></td><td><input name="ok" type="submit" value="提交"><input name="cancel" type="reset" value="重置"></td></tr></table></form></center></body></html>【步骤2】编写处理请求参数的Servlet,代码如下:import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class CheckParamServlet extends HttpServlet{public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {String name = request.getParameter("name");String pass = request.getParameter("pass");response.setContentType("text/html;charset=gb2312");PrintWriter out = response.getWriter();out.println("<html><head><title>Param Test</title></head>");out.println("<h3 align=center>你的用户名为:"+name+"</h3>");out.println("<h3 align=center>你的口令为:"+pass+"</h3>");out.println("</body></html>");}public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {doGet(request,response);}}【步骤3】修改web.xml文件,加入下面代码:<servlet><servlet-name>CheckParamServlet</servlet-name><servlet-class>CheckParamServlet</servlet-class></servlet><servlet-mapping><servlet-name>CheckParamServlet</servlet-name><url-pattern>/servlet/check</url-pattern></servlet-mapping>【步骤4】在浏览器的地址栏中输入下面URL:http://localhost:8080/ helloapp/loginform.html输入用户名和口令,如下图所示:loginform.html页面的运行结果然后点击“提交”按钮,经CheckParamServlet处理后返回的结果如下图所示::CheckParamServlet 程序的运行结果从这里我们可以看到,从服务器返回的汉字成了乱码。
原因是没有指定request的编码。
下面通过编写一个过滤器改变请求编码。
【步骤5】过滤器代码如下:package filter;import java.io.IOException;import javax.servlet.*;public class EncodingFilter implements Filter {protected String encoding = null;protected FilterConfig config;public void init(FilterConfig filterConfig) throws ServletException {this.config = filterConfig;// 得到在web.xml中配置的编码this.encoding = filterConfig.getInitParameter("Encoding");}public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException, ServletException {if (request.getCharacterEncoding() == null) {// 得到指定的编码String encode = getEncoding();if (encode != null) {//设置request的编码request.setCharacterEncoding(encode);response.setCharacterEncoding(encode);}}chain.doFilter(request, response);}protected String getEncoding() {return encoding;}public void destroy() {}}【步骤6】在web.xml文件中配置过滤器,加入下面代码:<filter><filter-name>EncodingFilter</filter-name><filter-class>filter.EncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>gb2312</param-value></init-param></filter><filter-mapping><filter-name>EncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>【步骤7】重复第(4)步操作,结果如下:EncodingFilter 程序的运行结果四、思考题1. 试简述过滤器有哪些功能?2. 如何理解过滤器链。