Filter,Listener定义区别
监听器和过滤器是一种特殊的servlet,其中监听器是用来处理服务器端事件,过滤器是在请求发出之后,响应到客户端之前的处理
用户的请求到达Servlet(JSP)之前,先经过过滤器处理,服务器的响应到达客户浏览器之前,也要先经过过滤器的处理。过滤器可以有多个,形成过滤器链filter chain。
哪些页面或者jsp需要用过滤器处理
-
应用程序中所有的资源 /*
-
指定的类型文件资源 *.html
-
指定的目录下的所有文件 /folder_name/*
-
指定的servlet myfilter.LoggerServlet
-
/simplefilter.html
-
指定目录下指定类型的单一文件 /dir_name/index.jsp
可以设置对何种请求方式使用过滤器
请求方式包括(request,forward,include,exception)
1 request 2 href="a.jsp" 3 response.sendRedirect("a.jsp"); 4 window.open("a.jsp"); 5 location.href="a.jsp"; 6 src="a.jsp" 7 ......... 8 forward 页面跳转 9 <jsp:forward .... 10 sendForward ... 11 12 include 13 有两种include其他页面的方法,一种是指令标签<%@ include file="xxx.jsp"%>,一种是动作标签<jsp:include page="xxx.jsp"/> 14 execetion 15 ......
应用场合
字符编码转换,权限管理,记录访问日志,过滤敏感词
案例:对字符编码进行过滤
-
创建新的web工程,在根目录下创建register与welcome两个jsp页面
-
创建三个包,分别为filter,listener,servlet等
-
添加JQuery包到项目中
-
创建listener,利用服务器启动创建三个用户并存放在HashMap中,并将HashMap中的信息存放在application中,代码如下:
1 package com.wy.listener; 2 3 import java.util.HashMap; 4 import javax.servlet.ServletContextEvent; 5 import javax.servlet.ServletContextListener; 6 import javax.servlet.annotation.WebListener; 7 8 /** 9 * Application Lifecycle Listener implementation class FilterListener 10 * 11 */ 12 @WebListener 13 public class FilterListener implements ServletContextListener { 14 15 /** 16 * Default constructor. 17 */ 18 public FilterListener() { 19 // TODO Auto-generated constructor stub 20 } 21 22 /** 23 * @see ServletContextListener#contextDestroyed(ServletContextEvent) 24 */ 25 public void contextDestroyed(ServletContextEvent arg0) { 26 // TODO Auto-generated method stub 27 } 28 29 /** 30 * @see ServletContextListener#contextInitialized(ServletContextEvent) 31 */ 32 public void contextInitialized(ServletContextEvent arg0) { 33 // TODO Auto-generated method stub 34 HashMap<String, String> map=new HashMap<String,String>(); 35 map.put("haha", "123456"); 36 map.put("xixi", "123456"); 37 map.put("youyou", "123456"); 38 //将信息存放在application中 39 arg0.getServletContext().setAttribute("USERS", map); 40 } 41 }
-
创建对应的register.jsp页面,并对用户名进行判定,查看看是否重复,当前输入的用户名是否可用,强制进行提交前要先检查用户名,代码如下:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>注册页面</title> 8 <script type="text/javascript" src="jslib/jquery.js"></script> 9 <script type="text/javascript"> 10 $(function(){ 11 $("#check").click(function(){ 12 $.post("checkIt",{"username":$("[name='userName']").val()},function(data){ 13 var s=data.split("$"); 14 $("[name='status']").val(s[0]); 15 $("#info").html(s[1]); 16 }); 17 }); 18 $("#sub").click(function(){ 19 if($("[name='status']").val()=="0"){ 20 $("#info").html("查看用户名是否重复"); 21 return false; 22 } 23 if($("[name='status']").val()=="1"){ 24 $("#info").html("用户名重复,输入新的用户名来检查"); 25 $("[name='status']").val(0); 26 return false; 27 } 28 return true; 29 }); 30 }); 31 </script> 32 </head> 33 <body> 34 <div id="info"></div> 35 <form action="welcome.jsp" method="post"> 36 <input type="hidden" name="status" value="0"/> 37 用户名:<input type="text" name="userName"/><br> 38 密 码:<input type="password" name="pwd"/><br> 39 <input type="button" id="check" value="检查用户"/> 40 <input type="submit" id="sub" value="提交"/> 41 </form> 42 </body> 43 </html>
-
创建servlet用于页面信息判断
1 package com.wy.servlet; 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.util.HashMap; 6 import javax.servlet.ServletException; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 /** 13 * Servlet implementation class checkIt 14 */ 15 @WebServlet("/checkIt") 16 public class checkIt extends HttpServlet { 17 private static final long serialVersionUID = 1L; 18 19 /** 20 * @see HttpServlet#HttpServlet() 21 */ 22 public checkIt() { 23 super(); 24 // TODO Auto-generated constructor stub 25 } 26 27 /** 28 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 29 */ 30 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 31 // TODO Auto-generated method stub 32 @SuppressWarnings("unchecked") 33 HashMap<String, String> map=(HashMap<String, String>) 34 request.getServletContext().getAttribute("USERS"); 35 String name=request.getParameter("username"); 36 PrintWriter out=response.getWriter(); 37 if(map.containsKey(name)){ 38 out.println("1$用户名已存在"); 39 }else { 40 out.println("2$用户名可用"); 41 } 42 } 43 44 /** 45 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 46 */ 47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 48 // TODO Auto-generated method stub 49 doGet(request, response); 50 } 51 }
-
创建对应的welcome.jsp用于提交之后的页面跳转,并输出用户的用户名信息,代码如下:
1 <%@page import="java.util.HashMap"%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 <!-- 将注册成功的用户提交到HashMap中,要从application中去存取,因为在监听器中HashMap的最新信息存放在application中 --> 12 <% 13 @SuppressWarnings("unchecked") 14 HashMap<String,String> map=(HashMap<String,String>) 15 request.getServletContext().getAttribute("USERS"); 16 String name=request.getParameter("userName"); 17 String pwd=request.getParameter("pwd"); 18 map.put(name, pwd); 19 %> 20 注册成功,欢迎你:<%=name %> 21 </body> 22 </html>
-
以上信息完成之后在运行过程中会出现输出提示信息乱码的问题,这个时候引入filter,只需要一个对应的filter类便能解决,编码如下:
在不使用过滤器的情况下也可以解决乱码问题,只是需要在每一个页面去进行处理,会有大量重复的编码
1 package com.wy.filter; 2 3 import java.io.IOException; 4 import javax.servlet.DispatcherType; 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.annotation.WebFilter; 12 13 /** 14 * Servlet Filter implementation class EncodingFilter 15 */ 16 @WebFilter(dispatcherTypes = { 17 DispatcherType.REQUEST, 18 DispatcherType.FORWARD, 19 DispatcherType.INCLUDE, 20 DispatcherType.ERROR 21 } 22 , urlPatterns = { "/*" }) 23 public class EncodingFilter implements Filter { 24 25 /** 26 * Default constructor. 27 */ 28 public EncodingFilter() { 29 // TODO Auto-generated constructor stub 30 } 31 32 /** 33 * @see Filter#destroy() 34 */ 35 public void destroy() { 36 // TODO Auto-generated method stub 37 } 38 39 /** 40 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 41 */ 42 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 43 // TODO Auto-generated method stub 44 // place your code here 45 /** 46 * 利用过滤器来设置提取输出编码,下面两行代码会在所有的页面中调用过滤 47 * 设置提取编码格式(在提取数据之前)request 48 * 设置响应输出编码格式(在输出数据之前)response 49 */ 50 request.setCharacterEncoding("utf-8"); 51 response.setCharacterEncoding("utf-8"); 52 // pass the request along the filter chain 53 chain.doFilter(request, response); 54 } 55 56 /** 57 * @see Filter#init(FilterConfig) 58 */ 59 public void init(FilterConfig fConfig) throws ServletException { 60 // TODO Auto-generated method stub 61 } 62 }