JavaWeb(五)Filter过滤器
Filter过滤器
Fileter介绍
Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如图:
Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源(拦截url)进行拦截后,WEB服务器每次在调用web资源之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
调用目标资源之前,让一段代码执行
是否调用目标资源(即是否让用户访问web资源)。
web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。
调用目标资源之后,让一段代码执行
开发Fileter步骤
Filter开发分为二个步骤:
- 编写java类实现Filter接口,并实现(三个方法)其doFilter方法。(现在也可以直接在Eclipse中创建Filter,可以不设置web.xml)
package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; /** * Servlet Filter implementation class FilterTest2 */ @WebFilter("/FilterTest2")//可以直接在此设置属性,不配置xml public class FilterTest2 implements Filter { public FilterTest2() { // TODO Auto-generated constructor stub } public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { } }
- 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。
<filter> <filter-name>TestFilTer1</filter-name> <filter-class>com.filter.TestFilTer1</filter-class><!-- 完整的限定类名,可以直接在类名Ctrl点击复制 --> </filter> <filter-mapping> <filter-name>TestFilTer1</filter-name> <url-pattern>/*</url-pattern><!-- *代表所有 --> </filter-mapping>
Filter链 --- FilterChain
- 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
- web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
Filter的生命周期
l init(FilterConfig filterConfig)throws ServletException:
和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法进行初始化。需要注意的是:filter对象只会创建一次,init方法也只会执行一次。
- 开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
l doFilter(ServletRequest,ServletResponse,FilterChain)
- 每次filter进行拦截都会执行
- 在实际开发中方法中参数request和response通常转换为HttpServletRequest和HttpServletResponse类型进行操作
HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp;
l destroy():
- 在Web容器卸载 Filter 对象之前被调用。
FilterConfig接口
l 用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:
- String getFilterName():得到filter的名称。
- String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.
- Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
- public ServletContext getServletContext():返回Servlet上下文对象的引用。
- Ø 注册
注册与映射Filter
l <filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
- <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
- <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
- <servlet-name>指定过滤器所拦截的Servlet名称。
- <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。
- <dispatcher> 子元素可以设置的值及其意义:
- REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
- INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
- ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Filter示例
过程:
web.xml中设置给index设置过滤
在过滤器中,获取session,为空也就是直接登访问index.jsp会跳转到登录页面
denglu.jsp,点击登录,跳转到chuli.jsp,设置session,在定向到index.jsp,获取到相应的session,通过进入
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>0826</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>TestFilTer1</filter-name> <filter-class>com.filter.TestFilTer1</filter-class><!-- 包名,可以直接在类名Ctrl点击复制 --> </filter> <filter-mapping> <filter-name>TestFilTer1</filter-name> <url-pattern>/index.jsp</url-pattern><!-- 访问index.jsp会启动过滤 --> </filter-mapping> </web-app>
package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet Filter implementation class TestFilTer1 */ @WebFilter("/TestFilTer1") public class TestFilTer1 implements Filter { /** * Default constructor. */ public TestFilTer1() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //先转型,可以使用转型后对象的方法 HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; //处理字符集 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); Object obj = request.getSession().getAttribute("currentUser");//获取session对象 if(obj == null) { response.sendRedirect("denglu.jsp"); } else { chain.doFilter(req, resp); } } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <a href="chuli.jsp">登录</a> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <% session.setAttribute("currentUser", "admin"); response.sendRedirect("index.jsp"); %> </body> </html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" import="java.util.ArrayList,com.util.User"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> 当前 </body> </html>
例子2
设置部分页面过滤
过滤器:
package com.hanqi.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SessionFilterTest implements Filter { //设置成员变量,获取需要过滤的页面 private String pages; @Override public void destroy() { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; // 获取当前请求 String uri = request.getRequestURI(); System.out.println("当前发送的请求: "+uri); // 获取不需要判断session 的请求们 String[] _pages = pages.split(";"); // 判断当前请求是否在不需要判断的请求里面 if(checkString(_pages, uri)) { // 放行 chain.doFilter(req, resp); } else { // 先判断session再放行 Object obj = request.getSession().getAttribute("currentUser"); if(obj==null) { response.sendRedirect("login.jsp"); } else { chain.doFilter(req, resp); } } } public static boolean checkString(String[] pages, String uri) { for(String s : pages) { if(uri.contains(s)) {//如果访问的地址包含了需要过滤的的页面 return true; } } return false; } @Override public void init(FilterConfig config) throws ServletException { String str = config.getInitParameter("page");//获取当前参数,即需要过滤的页面 this.setPages(str); System.out.println(str); } public String getPages() { return pages; } public void setPages(String pages) { this.pages = pages; } }
package com.hanqi.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class TestFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain arg2) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); arg2.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.hanqi.filter.TestFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>SessionFilter</filter-name> <filter-class>com.hanqi.filter.SessionFilterTest</filter-class> <init-param><!-- 设置可以放行的页面 --> <param-name>page</param-name> <param-value>login.jsp;LoginServlet;register.jsp;RegisterServlet</param-value> </init-param> </filter> <filter-mapping> <filter-name>SessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Servlet
package com.hanqi.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username); System.out.println(password); //简单验证如果指定的用户名和密码相同,设置session if("admin".equals(username)&&"12345".equals(password)) { request.getSession().setAttribute("currentUser", "admin"); response.sendRedirect("index.jsp"); } else { response.sendRedirect("fail.jsp"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
package com.hanqi.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class RegisterServlet */ @WebServlet("/RegisterServlet") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public RegisterServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String realname = request.getParameter("realname"); System.out.println(username); System.out.println(password); System.out.println(realname); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
Jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>登录失败</h1> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="RegisterServlet" method="post"> 用户名: <input type="text" name="username" /><br> 密码: <input type="text" name="password" /><br> 姓名: <input type="text" name="realname" /><br> <input type="submit" value="注册" /> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="LoginServlet" method="post"> 用户名: <input type="text" name="username" /><br> 密码: <input type="text" name="password" /><br> <input type="submit" value="登录" /> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>首页</h1> </body> </html>
全站统一字符编码过滤器
request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8");
禁用所有JSP页面缓存
因为动态页面数据,是由程序生成的,所以如果有缓存,就会发生,客户端查看数据不是最新数据情况 ,对于动态程序生成页面,设置浏览器端禁止缓存页面内容
response.setDateHeader("Expires",-1); response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma","no-cache");
将禁用缓存代码,提起到过滤器中,通过url配置,禁用所有JSP页面的缓存
JavaWeb(五)Filter过滤器的更多相关文章
- javaweb之Filter过滤器详解
快速入门 1.新建一个类,实现Filter接口 2.实现doFilter()方法,打印一句话,来证明能够进行拦截 3.在web.xml中进行配置(参照Servlet配置) 4.访问一个页面,看看能不能 ...
- 【JavaWeb】Filter 过滤器
Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...
- JavaWeb之Filter过滤器
原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼.言归正传,过滤器从字面理解她的话有拦网.过滤的功 ...
- JavaWeb -- Servlet Filter 过滤器
1. Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter.通过Filter技术,开发人员可以实现用户在 ...
- javaweb的Filter过滤器设置全站编码
FIlter配置全站编码有一种方法是重写getParameter方法,也就是继承HttpServletRequestWrapper在重写getParameter方法,还有一种就是如下: public ...
- Introduction of Servlet Filter(介绍javaweb组件之一过滤器filter)
javaweb的三大组件都需要交给web服务器运行,都需要在web.xml文件中配置. ①Servlet:javax.servlet.Servlet通过http协议接受客户端的请求,并作出响应的Jav ...
- JavaWeb 之 Filter:过滤器
一.Filter 概述 1.概念 web 中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能. 2.作用 一般用于完成通用的操作.如:登录验证.统一编码处理.敏感字符等功能 ...
- javaweb学习总结(四十二)——Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...
- javaWeb学习总结(10)- Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 web资源:例如Jsp, Servlet, 静 ...
随机推荐
- redhat系列linux系统 修改主机名的正确方法
##注:无特别说明,以下称呼的linux系统统一视为redhat系linux redhat系列linux系统 如果想修改主机名 很多人可能都会以为是: $hostname NEW-NAME 或者在 / ...
- 看懂 ,学会 .NET 事件的正确姿势
一.事件的本质 举个例子你是个取向正常的青年男性,有个身材火辣,年轻貌美,腿长肤白的美女,冲你一笑,给你讲了一个ABCD羊吃草的故事.你有什么反应?可能你关注点在于颜值,身材,故事,故事含 ...
- input复选框操作的部分高频率使用代码
1. 获取单个checkbox选中项(三种写法): $("input:checkbox:checked").val() 或者 $("input:[type='checkb ...
- Java 9 揭秘(15. 增强的弃用注解)
Tips 做一个终身学习的人. 主要介绍以下内容: 如何弃用API @deprecate Javadoc标签和@Deprecation注解在弃用的API中的角色 用于生成弃用警告的详细规则 在JDK ...
- 【Apache】 VirtualHost配置
主要配置两点: 1)配置vhost ,可单独建文件,也可直接在http.conf添加内容 如果单独建文件,查看http.conf 中Include 配置文件的路径,并在对应路径新建http_vhost ...
- 用java写一个用户登陆界面
一.课堂测试源代码及其结果截图 用java的swing写一个用户登录界面,采用网格布局.源代码如下: /** * */package LiuLijia; import java.awt.CardLay ...
- 使用pdfbox分页保存pdf为图片
一.背景 pdfbox作为Apache开源的PDF操作工具,允许创建新的PDF文档,操作现有文档,以及从文档中提取内容的能力.Apache PDFBox还包括一些命令行实用工具.本文楼主主要介绍其中的 ...
- Redola.Rpc 集成 Consul 服务发现
Redola.Rpc 解决了什么问题? Redola.Rpc 是一个使用 C# 开发的 RPC 框架,代码开源在 GitHub 上.目前版本仅支持 .NET Framework 4.6 以上版本,未来 ...
- WinFrom通过委托传递事件
今天一个功能需要动态创建pictruebox然后根据时间来倒叙显示,一开始对于这个需求摸不着头脑,后来在公司的大神帮助下实现了,话不多说具体实现上代码了: 1.动态添加控件并倒叙 首先添加一个用户控件 ...
- jQuery 去空
//去左右空格; function trim(s){ return s.replace(/(^\s*)|(\s*$)/g, ""); } //去掉字符串中所有空格(包括中间 ...