Servlet过滤器简介
![Servlet过滤器简介](https://img.360docs.net/imga0/04tabsvvl4oo3jg7r1z3-01.webp)
![Servlet过滤器简介](https://img.360docs.net/imga0/04tabsvvl4oo3jg7r1z3-62.webp)
14.1 Servlet过滤器简介
很早之前,Servlet API就已成为企业应用开发的重要工具。现在,Servlet中的过滤器和监听器功能则是对J2EE体系的一个补充。过滤器使得Servlet开发者能够在请求到达Servlet之前截取请求,在Servlet处理请求之后修改应答;而Servlet监听器可以监听客户端的请求、服务端的操作,通过监听器,可以自动激发一些操作,如监听应用的启动和停止等。本章将接着介绍Servlet过滤器和监听器的相关知识以及在实际开发中如何使用这些技术。
本章重点:
● Servlet过滤器简介
● Servlet过滤器的实现
● Servlet过滤文本信息
● Servlet监听器简介
14.1 Servlet过滤器简介
Servlet过滤器是小型的Web组件,能拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。过滤器是封装了一些功能的W eb组件,这些功能虽然很重要,但是对于处理客户机请求或发送响应来说不是决定性的。典型的例子包括记录关于请求和响应的数据、处理安全协议、管理会话属性等。
一个过滤器可以被关联到任意多个资源,一个资源也可以关联到任意多个过滤器。例如,在图14.1中就有如下的关联关系。
● F1同时被关联到S1、S2、S3。
● F1、F2、F3都和S2关联。
图14.1 Web资源与过滤器相关联
关联到同一个资源的过滤器形成一个过滤器链。例如,对S2进行访问时,F1、F 2、F3就形成了一个过滤器链,客户要访问资源S2,就要经过F1过滤器,然后是F2、F3,最后才是要访问的资源。如果在经过上面这3个过滤器时出现了错误或者被禁止访问,客户的请求就无法到达资源S2。在Servlet过滤器中,这个过滤器传递的过程是通过FilterChain.dofilter()方法实现的,当过滤器链到达末尾时,这个方法调用请求的资源。建立一个过滤器,一般需要下面4个步骤:
(1)建立一个实现Filter接口的类。这个类需要3个方法,即doFilter、ini t和destroy。doFilter方法包含主要的过滤代码(见第(2)步),在init方法中进行一些初始化的设置,而destroy方法进行清除过滤器占用的资源。(2)在doFilter方法中放入过滤行为。doFilter方法的第一个参数为Servle tRequest对象,为过滤器提供了对进入的信息(包括表单数据、cookie和HTTP 请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain,用来调用过滤器链中下一个过滤器或者在到达过滤器末尾时调用Servlet或JSP页。
(3)调用FilterChain对象的doFilter方法。Filter接口的doFilter方法将一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与Servlet或JSP页面关联,则Servlet或JSP页面被激活。
(4)对相应的Servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素对需要进行过滤的资源进行配置。
14.2 实现一个Servlet过滤器
Servlet过滤器API包含3个简单的接口,即Filter、FilterChain和FilterC onfig,它们位于javax.servlet包中。从编程的角度看,过滤器类将实现Filt er接口,然后使用这个过滤器类中的FilterChain和FilterConfig接口。该过滤器类的一个引用将传递给FilterChain对象,以允许过滤器将控制权传递给过滤器链中的下一个过滤器或者资源。FilterConfig对象将由容器提供给过滤器,以允许访问该过滤器的初始化数据。
14.2.1 编写实现类的程序
下面是一个简单的Servlet过滤器的例子,其中将获取一个Web服务器给客户提供服务需要的时间,也就是响应时间。
【本节示例参考:资料光盘\源代码\第14章\14-2\Servlet.java】
【实例14-1】这是一个实现类的程序,主要是使用过滤器处理请求,在处理时可能要耗费很多时间。
程序14-1 Servlet.java
01 package cn.ac.ict.Filter;
02 import java.io.IOException;
03 import java.io.PrintWriter;
04 import java.io.StringWriter;
05 import java.util.Date;
06 import javax.servlet.*;
07 public class ResponseTimeFilter implements Filter {
08 private FilterConfig filterConfig = null;
09 public void init(FilterConfig config) throws ServletException {//初始化函数
10 this.filterConfig = config;
11 }
12 public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) thro ws IOException, ServletException {
13 Date startTime, endTime;
14 double totalTime;
15 startTime = new Date();
16 StringWriter sw = new StringWriter();
17 PrintWriter writer = new PrintWriter(sw);
18 writer.println();
19 writer.println("ResponseTimeFilter Before call chain.doFilter");
20 chain.doFilter(request, response); //将请求转发给过滤器链中下一个资源
21 //下面是资源的响应时间
22 //下面计算开始时间和结束时间的差,也就是响应时间
23 endTime = new Date();
24 totalTime = endTime.getTime() - startTime.getTime();
25 totalTime = totalTime / 1000; //将毫秒时间转换为以秒为单位
26 writer.println("ResponseTimeFilter Before call chain.doFilter");
27 writer.println("===============");
28 writer.println("Total elapsed time is: " + totalTime + " seconds." );
29 writer.println("===============");
30 filterConfig.getServletContext().log(sw.getBuffer().toString()); //将信息输出到日志中
31 writer.flush();
32 }
33 public void destroy() {
34 this.filterConfig = null;
35 }
36 public FilterConfig getFilterConfig() {
37 return null;
38 }
39 public void setFilterConfig(FilterConfig config) {
40 }
41 }
【深入学习】当容器第一次加载该过滤器时,init()方法将被调用。该类在这个方法中包含了一个指向FilterConfig对象的引用。过滤器的大多数时间都消耗在执行过滤操作上,第20行中的doFilter()方法被容器调用,同时传入分别指向这个请求/响应链中的ServletRequest、ServletResponse和FilterChain对象的引用。然后过滤器就有机会处理请求,将处理任务传递给链中的下一个资源(通过调用FilterChain对象引用上的doFilter()方法),之后在处理控制权返回该过滤器时处理响应。
14.2.2 配置发布Servlet过滤器
发布Servlet过滤器时,必须在web.xml文件中加入
以上代码中,
当客户请求的URL和
说明:如果希望Servlet过滤器能过滤所有的客户请求,可以将
准备好上面的文件后,按照如下步骤即可发布这个Servlet过滤器。
(1)编译ResponseTimeFilter类,编译时,需要将Java Servlet API的包se rvlet-api.jar放到类路径中,编译后的类放到本章Web应用的WEB-INF\class es目录下,并且目录结构要与包的结构一致。
(2)在web.xml文件中按照上面说明的方法配置这个过滤器。
(3)为了观察这个过滤器的日志,应确保在server.xml文件的localhost对应的host元素中配置了如下的logger元素:
directory="logs" prefix="localhost_log." suffix=".txt" timestamp="true"/> 以上内容在默认情况下都是配置好的。 (4)启动Tomcat,在浏览器地址栏中输入http://localhost:8080/14/ShowCo unter.jsp,这时在 2009-05-26 23:03:42 StandardContext[/15] ResponseTimeFilter Before call chain.doFilter ResponseTimeFilter Before call chain.doFilter =============== Total elapsed time is: 0.0 seconds. =============== 说明:本例中访问的ShowCounter.jsp页面在本章的监听器部分介绍,如果读者不想跳跃着查看这个文件,可以尝试修改过滤器关联的URL,使得它可以过滤读者指定的资源。 14.3 ServletRequest和ServletResponse的包装类 Servlet过滤器能够对客户的请求和响应进行包装,并根据自定义的行为对请求和响应进行修改,这就是通过使用ServletRequest和ServletResponse的包装类——HttpServletRequestWrapper和HttpServletResponseWrapper类来实现的。这两个类提供了所有request和response方法的默认实现,并且默认地代 理了所有对原有request和response的调用。这也意味着,要改变一个方法的行为只需要从封装类继承并重新实现一个方法即可。 ● ServletRequestWrapper类:是ServletRequest的包装类,实现了ServletRequest接口,并对其方法提供了默认实现。 ● ServletResp onseWrapper类:是ServletResponse的包装类,实现了ServletResponse接口,并对其方法提供了默认实现。 14.4 用Servlet过滤器过滤文本信息 在14.3节中简单介绍了ServletRequest和ServletResponse的包装类,它们在过滤器设计中会经常被用到。本节将介绍一个使用HttpServletResponseWrappe r类的例子,客户输入的内容会被检查,如果存在不允许出现的信息,就会被过滤掉,而被替换成其他的字符。在这个例子中,客户输入用户名并发布自己的留言信息,然后提交给服务器,服务器再将这些信息反馈给客户。如果客户的留言中有指定的字符串,就会调用过滤器将这个字符串替换掉。 14.4.1 输出流管理类 在Servlet输出时可以选择不同的输出流,将它们集合在一起,即可很容易地对这些流进行管理,使用时也会更方便。如何使用输出流管理类,可以看下面的代码。 【本节示例参考:资料光盘\源代码\第14章\14-4\ByteArrayPrintWriter.java】 【实例14-2】将输出流进行方法的实例化,方便以后程序的调用。 程序14-2 ByteArrayPrintWriter.java 01 package cn.ac.ict; 02 import java.io.ByteArrayOutputStream; 03 import java.io.PrintWriter; 04 import javax.servlet.ServletOutputStream; 05 public class ByteArrayPrintWriter { 06 private ByteArrayOutputStream baos = new ByteArrayOutputStream(); 07 private PrintWriter pw = new PrintWriter(baos); 08 private ByteArrayOutputStream sos = new ByteArrayOutputStream(); 09 public ByteArrayPrintWriter(ByteArrayOutputStream aos) { 10 this.baos = aos; 11 } 12 //一个为空的构造方法 13 public ByteArrayPrintWriter() { 14 } 15 //使用字符输出流时调用获取输出流 16 public PrintWriter getWriter() { 17 return pw; 18 } 19 //使用字节输出流时调用获取输出流 20 public ByteArrayOutputStream getStream() { 21 return sos; 22 } 23 byte[] toByteArray() { 24 return baos.toByteArray(); 25 } 26 } 【深入学习】在第6、7、8行共定义了3个对象,一个是用字符流输出的,一个是用字节流输出的,但是它们最终都套接到类型为ByteArrayOutputStream的对象上,这个对象为它们提供了原始输出数据。 14.4.2 编写Servlet过滤器 前面编写了需要使用的辅助类,接下来即可开发进行实际过滤功能的文本过滤器。 【本节示例参考:资料光盘\源代码\第14章\14-4\TextModifierFilter.java】 【实例14-3】如何实现文本过滤器,代码(TextModifierFilter.java)如下: 程序14-3 TextModifierFilter.java 01 package cn.ac.ict; 02 import java.io.IOException; 03 import java.io.PrintWriter; 04 import java.util.Locale; 05 import javax.servlet.Filter; 06 import javax.servlet.FilterChain; 07 import javax.servlet.FilterConfig; 08 import javax.servlet.ServletException; 09 import javax.servlet.ServletOutputStream; 10 import javax.servlet.ServletRequest; 11 import javax.servlet.ServletResponse; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import com.sun.xml.internal.ws.util.ByteArrayBuffer; 15 public class TextModifierFilter implements Filter, ServletResponse { 16 private FilterConfig filterConfig; 17 private String searchStr; 18 private String replaceStr; 19 public void init(FilterConfig config) throws ServletException { 20 this.filterConfig = config; 21 //初始化要查找的字符串和替换后的字符串的值 22 this.searchStr = "search"; 23 this.replaceStr = "replace"; 24 } 25 public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) thro ws IOException, ServletException { 26 HttpServletRequest hsr = (HttpServletRequest)request; 27 final HttpServletResponse resp = (HttpServletResponse)response; 28 final ByteArrayBuffer pw = new ByteArrayBuffer(); 29 //构造响应包装类 30 TextModifierFilter tmrw = new TextModifierFilter(); 31 filterConfig.getServletContext().log("TextModifierFilter:Before call chain.doFilter"); 32 //将请求转发给Servlet,并获取响应 33 chain.doFilter(request,tmrw); 34 //下面的代码检查响应并对需要替换的字符进行替换 35 //将响应转化为byte数组 36 byte[] bytes = pw.toByteArray(); 37 if (bytes == null || (bytes.length == 0)) { 38 filterConfig.getServletContext().log("No content!"); 39 } 40 //将其转换为字符串便于查找 41 String content = new String(bytes); 42 String searchcontent = (new String(bytes)).toLowerCase(); 43 //查找指定字符出现的第一个位置 44 int endPos = searchcontent.indexOf(this.searchStr); 45 String returnStr; 46 //响应中包含这样一个字符串 47 if(endPos!=-1){ 48 String front_part_Str = content.substring(0,endPos); 49 returnStr=front_part_Str + ""+this.replaceStr+""+content.subst ring (endPos + this.searchStr.length()); 50 }else{ 51 //响应中不包含这样一个字符串 52 returnStr = content; 53 } 54 resp.setContentLength(returnStr.length()); 55 resp.getOutputStream().write(returnStr.getBytes()); 56 filterConfig.getServletContext().log("TextModifierFilter:After call chain.doFilter"); 57 } 58 public void destroy() { 59 this.filterConfig = null; 60 } 61 public FilterConfig getFilterConfig() { 62 return null; 63 } 64 public void setFilterConfig(FilterConfig config) { 65 } 66 public void flushBuffer() throws IOException { 67 } 68 public int getBufferSize() { 69 return 0; 70 } 71 public String getCharacterEncoding() { 72 return null; 73 } 74 public String getContentType() { 75 return null; 76 } 77 public Locale getLocale() { 78 return null; 79 } 80 public ServletOutputStream getOutputStream() throws IOException { 81 return null; 82 } 83 public PrintWriter getWriter() throws IOException { 84 return null; 85 } 86 public boolean isCommitted() { 87 return false; 88 } 89 public void reset() { 90 } 91 public void resetBuffer() { 92 } 93 public void setBufferSize(int arg0) { 94 } 95 public void setCharacterEncoding(String arg0) { 96 } 97 public void setContentLength(int arg0) { 98 } 99 public void setContentType(String arg0) { 100 } 101 public void setLocale(Locale arg0) { 102 } 103 } 【深入学习】上述代码的主要功能集中在第25行中的doFilter()方法中,在这个方法中构造了一个响应包装器。当调用chain.doFilter(request,tmrw)方法时,Servlet的响应都已经在响应包装器对象tmrw中了,之后即可调用相关的方法获取响应的内容,并进行适当的处理。 14.4.3 编写JSP和Servlet文件 前面已经开发完成了一个完整的文本过滤器的程序,这里将接着开发演示过滤器工作过程的JSP和Servlet文件。 【本节示例参考:资料光盘\源代码\第14章\14-4\textModifier.jsp】 【实例14-4】实现一个过滤器的程序,查看它的工作过程。首先来看利用JSP文件实现的代码。 程序14-4 textModifier.jsp 01 <%@ page language="java" pageEncoding="GB2312"%> 02 03
04
05
06
11
12
13
14
48
49
下面是用户提交输入留言信息的响应Servlet,其代码如下:
TextModiferServlet.java
01 package cn.ac.ict;
02 import java.io.IOException;
03 import javax.servlet.ServletException;
04 import javax.servlet.ServletOutputStream;
05 import javax.servlet.http.HttpServlet;
06 import javax.servlet.http.HttpServletRequest;
07 import javax.servlet.http.HttpServletResponse;
08 public class TextModiferServlet extends HttpServlet {
09 protected void doGet(HttpServletRequest request,HttpServletResponse response) throws Servlet Exception, IOException {
10 //设置响应的类型
11 response.setContentType("text/html;charset=gb2312");
12 ServletOutputStream out = response.getOutputStream();
13 //获取请求参数
14 String user = request.getParameter("username");
15 String content = request.getParameter("content");
16 String outstr = " ";
17 if (user != null) {
18 user = new String(user.getBytes("ISO8859-1"), "GB2312");
19 }
20 if (content != null) {
21 content = new String(content.getBytes("ISO8859-1"), "GB2312");
22 }
23 if ((user != null) && (content != null)) {
24 outstr = "User[" + user + "] say: '" + content + "'";
25 }
26 out.println("\r\n");
27 out
28 .println("\r\n");
29 out.println("\r\n");
30 out.println("
\r\n");31 out.println("
32 out.println("\r\n");
39 out.println("\r\n");
40 out.println("
\r\n");41 out.println("
\r\n");63 out.println("\r\n");
64 out.println("\r\n");
65 out.println("\r\n");
66 out.println("");
67 }
68 protected void doPost(HttpServletRequest request,HttpServletResponse response)throws Servlet Exception, IOException {
69 doGet(request, response);
70 }
71 }
【运行程序】准备好所有需要使用的文件后,可以按照如下步骤发布这个Web 应用。
(1)编译输出流管理类、响应包装器和过滤器的Java程序。编译时需要将ser vlet-api.jar放到类路径中,编译完成后,将得到的字节码文件复制到Web应用的WEB-INF\classes目录下,存放位置与包的结构一致。
(2)在Web应用的web.xml文件中配置使用的Servlet和Servlet过滤器,也就是在web.xml文件中添加如下代码:
01
图14.2 用户输入界面
图14.3 过滤效果
14.5 Servlet监听器简介
Servlet监听器是在Servlet 2.3版中引入的技术,它可以监听客户端的请求、服务端的操作等。Servlet监听器的很多特性与Servlet过滤器是一致的,它的很多概念也与Java中监听器的概念一致。Servlet监听器可以在特定事件发生时进行监听,并根据其作出相应的反应。
Servlet监听器的内容相对比较容易理解,下面将介绍Servlet监听器的常用类和接口,并通过例子讲述如何使用Servlet监听器。
14.5.1 监听服务器ServletContext对象
对ServletContext对象进行监听的接口有ServletContextAttributeListener 和ServletContextListener,可以分别用于监听ServletContext对象中属性的变化和ServletContext对象本身的变化。
1.ServletContextAttributeListener接口
实现ServletContextAttributeListener接口的监听器可以监听到ServletCont ext对象中属性的变化,其提供的方法有:
● void attributeAdded(ServletContextAttributeEvent scab)。
● void attributeRemoved(ServletContextAttrib uteEvent scab)。
● void attributeReplaced(ServletContextAttributeEvent scab)。
实现ServletContextAttributeListener接口可以监听对ServletContext属性的操作,当增加、删除、修改操作时,都会调用相应的方法。
● 当在ServletContext增加一个属性时,激发attributeAdded(ServletContextAttributeEvent scab)方法。
● 当在ServletContext删除一个属性时,激发attributeRemoved(ServletContextAttributeEvent scab)方法。
● 当在ServletContext属性被重新设置时,激发attributeReplaced(ServletContextAttributeEvent scab)方法。
2.ServletContextListener接口
实现ServletContextListener接口的监听器可以监听ServletContext对象本身的变化,其提供的方法有:
● void contextDestroyed(ServletContextEvent sce)。
● void contextInitialized(ServletContextEvent sce)。
实现ServletContextListener接口可以监听ServletContext的操作。
● 当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法。
● 当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
14.5.2 监听客户会话
对客户会话进行监听的接口有HttpSessionAttributeListener接口、HttpSess ionListener接口、HttpSessionActivationListener接口和HttpSessionBindi ngListener接口,可以分别用于监听HttpSession对象中属性的变化和HttpSe ssion对象本身状态的变化。
1.HttpSessionAttributeListener接口
实现HttpSessionAttributeListener接口的监听器可以监听到HttpSession对象中属性的变化,其提供的方法有:
● void attributeAdded(HttpSessionBindingEvent se)。
● void attributeRemoved(HttpSessionBindingEvent se)。
java过滤器
在基于 JSP 页面系统设计开发中,经常有一批页面需要对用户的身份进行验证,只有合法的用户才可以访问这些页面。显然可以在每个页面中添加身份验证,但这样做会给编程造成很大的麻烦,而且增加多余的代码。那么,如何解决JSP 页面用户身份验证呢? 二、JSP 页面中用户身份验证分析 在有多个用户使用的 JSP 系统中,为了保障系统的隐秘性安全性,就需要对登录系统的用户进行身份验证以保证用户身份的合法性。一个用户首次登录系统后会在session 对象中留下它的标识[1],就可以利用这个标识来完成各个JSP页面的用户身份验证。为了避免每个页面都进行身份验证而出现的麻烦,这里将通过Servlet 过滤器对JSP 页面统一进行身份验证。 三、用户身份验证的设计思路和技术要点 1、设计思路 Servlet 过滤器验证用户是围绕session 对象进行的。首先是实现用户登录的功能,在用户登录成功后产生一个session 标识;然后创建Servlet 过滤器,判断标识值是否正确,如果正确则通过验证,否则将给出提示信息并跳转到用户登录页面。 2、技术要点 使用 Servlet 过滤器实现JSP 页面中用户身份验证,首先必须实现Filter 接口,且重写doFilter() 方法,由doFilter() 方法去处理过滤业务;其次,在web.xml 文件中配置Servlet 过滤器,指定过滤器的名称、过滤器包所在类的名称及过滤器的映射范围等[2]。 四、JSP 页面中用户身份验证的实现 1、用户身份合法性确认 为了能够使用 Servlet 过滤器实现用户对JSP 页面访问的合法性验证,首先需要根据用户登录号和密码等与数据库中的信息相比较,若能匹配成功,则是用户登录成功,就用session 对象存储该用户的标识;然后再由Servlet 过滤器实现对用户访问的各个页面的过滤。存储用户登录成功的session 标识的核心代码为:session.setAttribute("user", 用户登录号 )。 2、Servlet 过滤器的实现 用 Servlet 过滤器实现用户身份验证的关键代码如下: package hzu.util.filters; public class UserFilter extends HttpServlet implements Filter { private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException{ this.filterConfig=filterConfig;
使用Servlet过滤器实现用户登录验证
package Filters;import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class LogOrNot implements javax.servlet.Filter { private FilterConfig config; private String logon_page; private String home_page; public void destroy() { config = null; } public void init(FilterConfig filterconfig) throws ServletException { // 从部署描述符中获取登录页面和首页的URI config = filterconfig; logon_page = filterconfig.getInitParameter("LOGON_URI"); home_page = filterconfig.getInitParameter("HOME_URI"); System.out.println(home_page); if (null == logon_page || null == home_page) { throw new ServletException("没有找到登录页面或主页"); } } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse rpo = (HttpServletResponse) response; javax.servlet.http.HttpSession session = req.getSession(); try { req.setCharacterEncoding("utf-8"); } catch (Exception e1) { e1.printStackTrace(); } String userId = (String) session.getAttribute("UserId"); String request_uri = req.getRequestURI().toUpperCase();// 得到用户请求的URI String ctxPath = req.getContextPath();// 得到web应用程序的上下文路径 String uri = request_uri.substring(ctxPath.length()); // 去除上下文路径,得到剩余部分的路径
Servlet过滤器使用
Servlet过滤器使用(javax.servlet.Filter)作者:本站原创发布时间:2010-06-10来源:JA V A中文网点我投稿 教程由JA V A中文网整理校对发布(https://www.360docs.net/doc/a0507967.html,) 过滤器(Filter)的概念 过滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求和响应。 在请求到达Servlet/JSP之前,过滤器截获请求。 在响应送给客户端之前,过滤器截获响应。 多个过滤器形成一个过滤器链,过滤器链中不同过滤器的先后顺序由部署文件web.xml中过滤器映射
实验六 Servlet过滤器的使用
实验六Servlet过滤器的使用 一、实验目的 1. 了解过滤器的作用; 2. 掌握过滤器的开发与部署的步骤; 3. 了解过滤器链。 二、实验原理 过滤器是web服务器上的组件,它们对客户和资源之间的请求和响应进行过滤。 过滤器的工作原理是:当servlet容器接收到对某个资源的请求,它要检查是否有过滤器与之关联。如果有过滤器与该资源关联,servlet容器将把该请求发送给过滤器。在过滤器处理完请求后,它将做下面3件事: ?产生响应并将其返回给客户; ?如果有过滤器链,它将把(修改过或没有修改过)请求传递给下一个过滤器; ?将请求传递给不同的资源。 当请求返回到客户时,它是以相反的方向经过同一组过滤器返回。过滤器链中的每个过滤器够可能修改响应。 过滤器API主要包括:Filter、FilterConfig和FilterChain接口。 三、实验内容与步骤 编写一个过滤器改变请求编码。 【步骤1】编写一个loginform.html文件,代码如下:
请输入用户名和口令:
java web 过滤器
传智播客java web 过滤器 今日学习Servlet的过滤器部分,百闻不如一见。以后我在课后做练习时,发现多个Servlet 之间转发容易产生问题。 详细出处参考:https://www.360docs.net/doc/a0507967.html,/article/21017.htm根本不利于使用,Servlet应该本是为简化工作而创造的啊!我当时觉得是我的设计框架产生了问题。第二天我便问方老师,确实是使用上有些问题。比如,显示访问计数,我把它单独写成了一个Servlet,什么地方需要它时,便由那个Servlet.include引用计数的Servlet。但这样总会产生一些问题和使用上的不便。比如include的Servlet必须使用相同的流,如果使用forward后任何输出都无效了。 方老师当时建议,把有些功能写到一起。但最后提到了过滤器,那时我便对过滤器产生了兴趣,今日也终于一睹芳容!让人十分喜欢! ServletFilter,Servlet过滤器: Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter 技术可以对web服务器管理的所有web资源:Jsp, Servlet, 静态图片文件或静态html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。 ServletAPI提供了一个Filter接口,实现这个接口的Servlet就是一个过虑器。过虑器在WEB 应用访问流程中如下: 由图可见,只要我们编写了过滤器,可以对一切访问WEB应用的连接进行过滤。比如,用户访问权限、统一WEB编码… Filter是如何实现拦截的? 实现了Filter接口的Servlet是过滤器,因为Filter接口有一个doFilter(ServletRequest request, ServletResponse response, FilterChain chain)方法,只要用户访问我们在web.xml中配置的映射目录,服务器便会调用过滤器的doFilter方法。我们在这里实现过虑功能代码,当我们调用chain.doFilter(request, response);方法时,将请求反给服务器服务器再去调用相当的Servlet。如果我们不调用此方法,说明拒绝了用户的请求。 Filter开发入门: 在WEB应用中添加一个过滤器,有两步工作需要完成: 1.编写实现了Filter接口的Servlet——过滤器。 2.在web.xml中配置过滤器: (1).
Java过滤器Filter使用说明
Java 过滤器 1. 过滤器的产生背景 在基于JSP 页面开发的Web 项目中,会遇到一种情况,除了登陆页面或者注册页面以外,其它页面在用户未登陆的情况下是不允许访问的。对用户身份的验证是基于session 实现的,即在登陆成功后在session 中放入标识,当用户再次访问其它页面时,根据session 的标识来确认用户是否可以访问。这样的话,在很多页面中都需要添加判断代码,同样代码的重复增加了多余的代码,不符合Java 编程习惯且不利于维护。而过滤器的产生解决了这一问题。 2. 过滤器的实现 使用Servlet 过滤器实现JSP 页面中的用户身份验证,首先必须实现Filter 接口,且重写doFilter()方法,由doFilter()方法去处理过滤业务;其次,在web.xml 文件中配置Servlet 过滤器,指定过滤器的名称、过滤器包所在类的名称及过滤器的映射范围等。 3. 过滤器的介绍 3.1 Servlet 过滤器接口的构成 所有的Servlet 过滤器都必须实现javax.servlet.filter 接口,该接口中定义了3个过滤器必须实现的方法: void init(FilterConfig):过滤器的初始化方法,Servlet 容器在创建过滤器实例时调用这个方法,在这个方法中可以读出在web.xml 文件中为该过滤器配置的初始化参数。 void doFilter(ServletRequest,ServletResponse,FilterChain):用于完成实际的过滤操作,当客户请求访问与过滤器相关联的URL 时,Servlet 容器将先调用过滤器的这个方法,FilterChain 参数用于访问后续过滤器。 void destroy():过滤器在被取消前执行这个方法,释放过滤器申请的资源。 3.2创建一个Servlet 过滤器需要下面的步骤: 1.创建一个实现了javax.servlet.Filter 接口的类。 2.重写init(FilterConfig)方法,读入为过滤器配置的初始化参数,申请过滤器需要的资源 3.重写方法doFilter(ServletRequest,ServletResponse,FilterChain),完成过滤操作,可以从ServletRequest 参数中得到全部的请求信息,从ServletResponse 参数中得到全部的响应信息。 4.在doFilter()方法的最后,使用FilterChain 参数的doFilter()方法将请求和响应后传。 5.对响应的Servlet 程序和JSP 页面注册过滤器,在部署描述文件(web.xml)中使用
javaweb中的过滤器
day15 过滤器(Filter) 过滤器概述 1什么是过滤器 过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。 当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。 其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet 的代码后,还会执行Filter后面的代码。 2过滤器之hello world 其实过滤器与Servlet很相似,我们回忆一下如果写的第一个Servlet应用!写一个类,实现Servlet
应该没有问题吧,都可以看懂吧! OK了,现在可以尝试去访问index.jsp页面了,看看是什么效果! 当用户访问index.jsp页面时,会执行HelloFilter的doFilter()方法!在我们的示例中,index.jsp 页面是不会被执行的,如果想执行index.jsp页面,那么我们需要放行!
有很多同学总是错误的认为,一个请求在给客户端输出之后就算是结束了,这是不对的!其实很多事情都需要在给客户端响应之后才能完成! 过滤器详细 1过滤器的生命周期 我们已经学习过Servlet的生命周期,那么Filter的生命周期也就没有什么难度了! ●init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实 例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次; ●doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访 问“目标资源(
过滤器详解
使用filter过滤请求 注意 Filter虽然很常用,但是覆盖的范围太广,这里我们只介绍设置编码和控制权限的过滤器,其他的使用方式还需要大家自行积累。 如果你不满足以下任一条件,请继续阅读,否则请跳过此后的部分,进入下一章:第 8 章配置listener监听器。 1.了解Filter的使用。 7.1. 批量设置请求编码 编码问题会不会成为中国人学java的标志呢? 通过之前的讨论第 2.2.2 节“POST乱码”,我们知道为了避免提交数据的乱码问题,需要在每次使用请求之前设置编码格式。在你复制粘贴了无数次request.setCharacterEncoding("gb2312");后,有没有想要一劳永逸的方法呢?能不能一次性修改所有请求的编码呢? 用Filter吧,它的名字是过滤器,可以批量拦截修改servlet的请求和响应。 我们编写一个EncodingFilter.java,来批量设置请求编码。
在此EncodingFilter实现了Filter接口,Filter接口中定义的三个方法都要在EncodingFilter中实现,其中doFilter()的代码实现主要的功能:为请求设置gb2312编码并执行chain.doFilter()继续下面的操作。 与servlet相似,为了让filter发挥作用还需要在web.xml进行配置。 filter标签部分定义使用的过滤器,filter-mapping标签告诉服务器把哪些请求交给过滤器处理。这里的/*表示所有请求,/表示根路径,*(星号)代表所有请求,加在一起就变成了根路径下的所有请求。 这样,所有的请求都会先被EncodingFilter拦截,并在请求里设置上指定的gb2312编码。 例子在lingo-sample/07-01目录下,这次我们不需要在test.jsp中为请求设置编码也可以得到正常的中文参数了,EncodingFilter圆满的完成了它的工作。 7.2. 用filter控制用户访问权限 出于信息安全和其他一些原因的考虑,项目中的一些页面要求用户满足了一定条件之后才能访问。比如,让用户输入帐号和密码,如果输入的信息正确就在
使用Servlet过滤器验证Session
使用Servlet过滤器验证Session 登录模块至少需要以下几个页面: JSP模块: 1.输入用户信息页面(login.jsp); 2.登录成功欢迎页面(pass.jsp)(检查Session设置); 3.注销登录页面(logout.jsp)。 Servlet模块: 1.检查Cookie页面(index.mgc)(servlet:CheckCookie.java); 2.用户合法性验证页面(check.mgc)(servlet:CheckMember.java); Filter模块: 验证Session(SessionFilter.java); DAO模块: 1.VO对象类(Member.java); 2.数据库操作接口类(MemberDAO.java); 3.数据库连接类(DataBaseConnection.java); 4.数据库操作类(DAOMemberImpl.java); 5.工厂类(DAOFactory.java)。 数据库:member.mdb 结构图: --------------------------------------------------------------------- index.mgc | |判断Cookie中有无用户名、密码 ---------------------- | Y N | | V | login.jsp<-------------------- | |输入用户名、密码 | | V | ---------------->check.mgc | |调用DAO模块 | 查询数据库 V | member.mdb<--->DAO |
JAVA WEB 中Servlet过滤器的使用
JAVA WEB 中Servlet过滤器的使用 JAVA 2008-08-07 17:39:00 阅读175 评论0 字号:大中小订阅 一、Servlet过滤器的概念: Servlet过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和 修改。 Servlet过滤器本身并不产生请求和响应对象,它只能提供过滤作用。Servlet过期能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容;在Servlet被调用之后检查Response对 象,修改Response Header和Response内容。 Servlet过期负责过滤的Web组件可以是Servlet、JSP或者HTML文件。 二、Servlet过滤器的特点: A.Servlet过滤器可以检查和修改ServletRequest和ServletResponse对象 B.Servlet过滤器可以被指定和特定的URL关联,只有当客户请求访问该URL时,才会触发过滤器C.Servlet过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象 三、Servlet过滤器的作用: A.查询请求并作出相应的行动。 B.阻塞请求-响应对,使其不能进一步传递。 C.修改请求的头部和数据。用户可以提供自定义的请求。 D.修改响应的头部和数据。用户可以通过提供定制的响应版本实现。 E.与外部资源进行交互。 四、Servlet过滤器的适用场合: A.认证过滤 B.登录和审核过滤 C.图像转换过滤 D.数据压缩过滤 E.加密过滤 F.令牌过滤 G.资源访问触发事件过滤 H.XSL/T过滤 I.Mime-type过滤 五、Servlet过滤器接口的构成: 所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法: A.init(FilterConfig): 这是Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数 B.doFilter(ServletRequest,ServletResponse,FilterChain): 这个方法完成实际的过滤操作,当客户请求访问于过滤器关联的URL时,Servlet容器将先调用过滤器的
使用过滤器控制用户登录
学jsp这么长时间,做的项目也有七八个了,可所有的项目都是用户登录就直接跳转到其拥有权限的页面,或者显示可访问页面的链接。使用这种方式来幼稚地控制访问权限。从来没有想过如果我没有登录,直接输入地址也可以直接访问用户的页面的。 在jsp中权限的控制是通过Filter过滤器来实现的,所有的开发框架中都集成有Filter,如果不适用开发框架则有如下实现方法: LoginFilter.java public class LoginFilter implements Filter { private String permitUrls[] = null; private String gotoUrl = null; public void destroy() { // TODO Auto-generated method stub permitUrls = null; gotoUrl = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest res=(HttpServletRequest) request; HttpServletResponse resp=(HttpServletResponse)response;
if(!isPermitUrl(request)){ if(filterCurrUrl(request)){ System.out.println("--->请登录"); resp.sendRedirect(res.getContextPath()+gotoUrl); return; } } System.out.println("--->允许访问"); chain.doFilter(request, response); } public boolean filterCurrUrl(ServletRequest request){ boolean filter=false; HttpServletRequest res=(HttpServletRequest) request; User user =(User) res.getSession().getAttribute("user"); if(null==user) filter=true;
Filter过滤器详解
(牛人的经典教材) Java Filter过滤机制详解 一、什么是Filter Filter 技术是servlet 2.3 新增加的功能.servlet2.3是sun公司与2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则.由于众多的参与者的共同努力,servlet2.3比以往功能都强大了许多,而且性能也有了大幅提高. 它新增加的功能包括: 1. 应用程序生命周期事件控制; 2. 新的国际化; 3. 澄清了类的装载规则; 4. 新的错误及安全属性; 5. 不赞成使用HttpUtils 类; 6. 各种有用的方法; 7. 阐明并扩展了几个servlet DTD; 8. filter功能. 其中最重要的就是filter功能.它使用户可以改变一个request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).一个filter 包括: 1. 在servlet被调用之前截获; 2. 在servlet被调用之前检查servlet request; 3. 根据需要修改request头和request数据; 4. 根据需要修改response头和response数据; 5. 在servlet被调用之后截获.
你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用.几个实用的filter 包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等. 一个filter必须实现javax.servlet.Filter接口定义的三个方法: doFilter、init 和destroy。(在三个方法在后面后有详细的介绍). 二、Filter体系结构 2.1、Filter工作原理(执行流程) 当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。 **************************************************************************************** ******************************** 在这里,我要插几句——关于过滤链的问题:上面说了,当一个请求符合某个过滤器的过滤条件时该请求就会交给这个过滤器去处理。那么当两个过滤器同时过滤一个请求时谁先谁后呢?这就涉及到了过滤链FilterChain。 所有的奥秘都在Filter的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法。(注:这一点Filter和Servlet是不一样的,具体请参看我的另一篇文章:Servlet和Filter 映射匹配原则之异同)执行的顺序就如下图所示,执行第一个过滤器的 chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的 chain.doFilter()之后的代码,最后返回响应。
实验8 Servlet过滤器与监听器
https://www.360docs.net/doc/a0507967.html,/view/4636a813a2161479 1711280c.html 实验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 {
servlet过滤器配置及运行过程
Servlet API的2.3版本的一个新功能就是能够为servlet和JSP页面定义过滤器。过滤器提供了某些早期服务器所支持的非标准“servlet链接”的一种功能强大且标准的替代品。 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择: 以常规的方式调用资源(即,调用servlet或JSP页面)。 利用修改过的请求信息调用资源。 调用资源,但在发送响应到客户机前对其进行修改。 阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。 过滤器只在与servlet规范2.3版兼容的服务器上有作用。如果你的Web应用需要支持旧版服务器,就不能使用过滤器。 1.建立基本过滤器 建立一个过滤器涉及下列五个步骤: 1)建立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy。doFilter 方法包含主要的过滤代码(见第2步),init方法建立设置操作,而destroy方法进行清楚。 2)在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为 FilterChain,如下一步所述,此参数用来调用servlet或JSP页。 3)调用FilterChain对象的doFilter方法。 Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。 4)对相应的servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和 filter-mapping元素。 5)禁用激活器servlet。防止用户利用缺省servlet URL绕过过滤器设置。 1.1 建立一个实现Filter接口的类 所有过滤器都必须实现javax.servlet.Filter。这个接口包含三个方法,分别为doFilter、init和destroy。 1、public void doFilter(ServletRequset request, ServletResponse response, FilterChain chain) thows ServletException, IOException 每当调用一个过滤器(即,每次请求与此过滤器相关的servlet或JSP页面)时,就执行其doFilter 方法。正是这个方法包含了大部分过滤逻辑。 第一个参数为与传入请求有关的ServletRequest。对于简单的过滤器,大多数过滤逻辑是基于这个对象的。如果处理HTTP请求,并且需要访问诸如 getHeader或getCookies等在ServletRequest中无法得到的方法,就要把此对象构造成 HttpServletRequest。 第二个参数为ServletResponse。除了在两个情形下要使用它以外,通常忽略这个参数。首先,如果希望完全阻塞对相关servlet或JSP页面的访问。可调用response.getWriter并直接发送一个响应到客户机。第7节给出详细内容,第8节给出一个例子。其次,如果希望修改相关的servlet或JSP 页面的输出,可把响应包含在一个收集所有发送到它的输出的对象中。然后,在调用 serlvet或JSP 页面后,过滤器可检查输出,如果合适就修改它,之后发送到客户机。详情请参阅第9节。 DoFilter的最后一个参数为FilterChain对象。对此对象调用doFilter以激活与servlet或JSP页面相关的下一个过滤器。如果没有另一个相关的过滤器,则对doFilter的调用激活servlet或JSP本身。 2、public void init(FilterConfig config) thows ServletException init 方法只在此过滤器第一次初始化时执行,不是每次调用过滤器都执行它。对于简单的过滤器,
java过滤器应用
1:Servletf过虑器基础: Servlet过滤器是Servlet的一种特殊用法,主要用来完成一些通用的操作。比如编码的过滤,判断用户的登陆状态等等。Servlet过虑的适用场合: A.认证过滤 B.登录和审核过滤 C.图像转换过滤 D.数据压缩过滤 E.加密过滤 F.令牌过滤 G.资源访问触发事件过滤 Servlet过滤器接口的构成: 所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法: 方法说明 init(FilterConfig cfg)这是Servlet过滤器的初始化方法,性质等同与servlet的init方法。doFilter(ServletRequest,ServletResponse,FilterChain)完成实际的过滤操作,当请求访问过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器 Destroy()Servlet容器在销毁过滤器实例前调用该方法,这个方法中可以释放Servlet过滤器占用的资源。性质等同与servlet的destory()方法。 Servlet过滤器创建步骤: A.实现javax.servlet.Filter接口的servlet类 B.实现init方法,读取过滤器的初始化函数。 C.实现doFilter方法。完成对请求或过滤的响应 D.调用FilterChain接口对像的doFilter方法,向后续的过滤器传递请求或响应 E.在web.xml中配置Filter 2.使用过滤器处理中文问题 3.使用过滤器认证用户: 每个过滤器也可以配置初始化参数,可以将不需要过滤的地址配置到这个Filter的配置参数中,过滤时,如果请求地址在配置参数中,则放行,这样避免了在程序中硬编码。每个Filter 中初始化时,都可以得到配置对象,在Filter中配置二个不需要过滤的地址,一个是登陆页面,一个是执行登陆认证的Servlet 示例: Public class EncodingFilter implements Filter{ Private static String encoding; Public void destroy(){ System.out.println(“过滤器被销毁!!!!!”);//WEB应用被卸载时,过滤器即被销毁。 } Public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException{ System.out.println(“step1^^^^^^^^^^^^^); request.setCharacterEncoding(encoding); chain.doFilter(request,response); System.out.println(“step2^^^^^^^^^^^^^^^^^^^^^^^^^^^^^”);