javaee学习之路(六)Servlet过滤器
来源:互联网 发布:衣柜画图软件 编辑:程序博客网 时间:2024/06/15 04:10
例1、初步认识过滤器。
第一步、BaseFilter.java
package cn.itcast.filter;import *;public class BaseFilter implements Filter{ public BaseFilter(){//先实例化,后初始化 System.out.println("BaseFilter方法"); } /* * 初始化方法 servlet容器调用该方法 ==Servlet init方法 * *能被调用一次 */ public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init方法"); } /** * 处理客户请求的方法 * * servlet容器调用该方法 = servlet service()方法 * * 能被调用多次 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws xception { System.out.println("doFilter方法"); HttpServletRequest res=(HttpServletRequest)request; System.out.println("res.getServletPath()"+res.getServletPath()); //放行,控制后面的资源是否执行 chain.doFilter(request, response); } /** * 3.释放资源的方法 * * servlet容器调用该方法==servlet中的destroy方法 */ public void destroy() { System.out.println("destroy方法"); }}
第二步、web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- 注册filter --><filter> <!-- 注册的过滤器的名称 --> <filter-name>BaseFilter</filter-name> <!-- filter的完整路径 --> <filter-class>cn.itcast.filter.BaseFilter</filter-class></filter><!-- 配置过滤器映射 --><filter-mapping> <!-- 上面注册的filter的名称 --> <filter-name>BaseFilter</filter-name> <!-- 拦截所有的请求 --> <url-pattern>/*</url-pattern></filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>
第三步、启动tomcat服务器,在IE中键入http://localhost:8080/day17Filter/观察结果
……
2012-10-23 19:10:14 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.20
BaseFilter方法
init方法
……
信息: Server startup in 5301 ms
doFilter方法
res.getServletPath()/index.jsp
例2、过滤器的详细应用。
第一步、BaseFilter.java
package cn.itcast.filter;import *;public class BaseFilter implements Filter{ public BaseFilter(){//先实例化,后初始化 System.out.println("BaseFilter方法"); } /* * 初始化方法 servlet容器调用该方法 ==Servlet init方法 * *能被调用一次 * *FilterConfig类似于servletConfig */ public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init方法"); System.out.println("filterConfig:"+filterConfig);/********************************************************************************/ System.out.println("获取过滤器的名称:"+filterConfig.getFilterName());//web.xml中配置的/********************************************************************************/ /* * <init-param> <param-name>test1</param-name> <param-value>a1</param-value> </init-param> <init-param> <param-name>test2</param-name> <param-value>a2</param-value> </init-param> */ String initparam1=filterConfig.getInitParameter("test1"); System.out.println("initparam1"+initparam1);/********************************************************************************/ java.util.Enumeration<String> em=filterConfig.getInitParameterNames(); while(em.hasMoreElements()){ String paramName=em.nextElement(); String paramValue=filterConfig.getInitParameter(paramName); System.out.println(paramName+":"+paramValue); } /* * <context-param> <param-name>testContext</param-name> <param-value>xxxxxxxxxx</param-value> </context-param> */ //获取上下文对象,相当有用/********************************************************************************/ ServletContext sc=filterConfig.getServletContext(); String str=sc.getInitParameter("testContext"); System.out.println("str"+str); } /** * 处理客户请求的方法 * * servlet容器调用该方法 = servlet service()方法 * * 能被调用多次 * request:客户端的请求信息 * response:对客户端的响应信息 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception { System.out.println("doFilter方法"); HttpServletRequest res=(HttpServletRequest)request;//注意要转型 HttpServletResponse req=(HttpServletResponse)response; System.out.println("res.getContextPath():"+res.getContextPath()); System.out.println("res.getRequestURL():"+res.getRequestURL()); System.out.println("res.getRequestURI():"+res.getRequestURI()); System.out.println("res.getServletPath()"+res.getServletPath()); //放行 chain.doFilter(request, response);//也可以是res,req } /** * 3.释放资源的方法 * * servlet容器调用该方法==servlet中的destroy方法 */ public void destroy() { System.out.println("destroy方法"); }}
第二步、web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app ……<context-param> <param-name>testContext</param-name> <param-value>xxxxxxxxxx</param-value></context-param><!-- 注册filter --><filter> <!-- 注册的过滤器的名称 --> <filter-name>BaseFilter</filter-name> <!-- filter的完整路径 --> <filter-class>cn.itcast.filter.BaseFilter</filter-class> <init-param> <param-name>test1</param-name> <param-value>a1</param-value> </init-param> <init-param> <param-name>test2</param-name> <param-value>a2</param-value> </init-param></filter><!-- 配置过滤器映射 --><filter-mapping> <!-- 上面注册的filter的名称 --> <filter-name>BaseFilter</filter-name> <!-- 拦截所有的请求 --> <url-pattern>/*</url-pattern></filter-mapping>
……
第三步、启动服务器,在IE中键入:http://localhost:8080/day17Filter/并观察结果
……
信息: Starting Servlet Engine: Apache Tomcat/6.0.20
BaseFilter方法
init方法
filterConfig:ApplicationFilterConfig[name=BaseFilter, filterClass=cn.itcast.filter.BaseFilter]
获取过滤器的名称:BaseFilter
initparam1a1
test1:a1
test2:a2
strxxxxxxxxxx
……
信息: Server startup in 3873 ms
doFilter方法
res.getContextPath():/day17Filter
res.getRequestURL():http://localhost:8080/day17Filter/
res.getRequestURI():/day17Filter/
res.getServletPath()/index.jsp
例3:字符编码的过滤器:通过配置参数encoding致命使用何种字符编码,以处理html Form请求参数的中文问题
第一步、
第二步、login.jsp
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>
……
<div id="container"> <div id="login"> <div id="form"> <form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post"> <div id="input"> <div> 用户:<input type="text" name="username"/><br/></div> <div> 密码:<input type="password" name="password"/><br/></div> </div> <div id="btn"> <input type="submit" value="登录"/>
……
第三步、LoginServlet.java
package cn.itcast.web;import *;public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request.setCharacterEncoding("UTF-8");//没有上面一行,提交表单时中文会出现乱码问题,用过滤器来处理 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String username=request.getParameter("username"); System.out.println("username"+username); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
第四步、
package cn.itcast.filter;import *;public class CharacterEncodingFilter implements Filter { String encoding; public void init(FilterConfig filterConfig) throws ServletException { /* * <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> */ String encoding = filterConfig.getInitParameter("encoding"); this.encoding=encoding; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; if(req.getCharacterEncoding()==null){ if(this.encoding!=null){ //设置字符编码 request.setCharacterEncoding(this.encoding); } } //放行 chain.doFilter(request, response); } public void destroy() { }}
第五步、
<filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <!-- 使用servlet的名称 也就是Servlet中servlet-name标签的值 --> <servlet-name>LoginServlet</servlet-name> </filter-mapping>
映射Filter(串联一)
1、 通天一个Filter设置多个映射
2、 在同一个web.Xml文件中可以为同一个Filter设置多个映射,若一个Filter链中多次出现了同一个Filter程序,这个Filter程序的拦截处理过程将被执行多次
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>cn.itcast.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> ① <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/a/b/b.jsp</url-pattern> </filter-mapping> ② <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/a/a.jsp</url-pattern> </filter-mapping> ③<filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/login.jsp</url-pattern> </filter-mapping>
如果filter-mapping的内容都要执行的话,过滤器的执行顺序按照filter_mapping在web.xml文件中的顺序执行。
上面的执行顺序为:①②③
例5、项目应用2:是浏览器不缓存页面的过滤器:
* 有三个HTTP响应头字段都可以禁止浏览器缓存当前页面,他们在Servlet中的实例代码:
//设定该网页的到期时间,一旦过期则必须到服务器重新调用
Response.setDateHeader(“Expires”,-1);
//Cache-Control指定请求和响应遵循的缓存机制 no-cache只是请求或响应消息不能缓存
Response.setHeader(“Cache-Control”,”no-cache”);
//是用于设定禁止浏览器从本地机的缓存中调阅页面内容,设定后一旦离开网页就无法从Cache中再调出
Response.setHeader(“Pragma”,”no-cache”);
- 并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头
问题演示:
第一步、pic.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>pic.html</title> </head> <body> <img src="./1.jpg"/> <br/> <a href="./test.jsp">test.jsp</a> </body></html>
第二步、test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> </head> <body> <a href="./pic.html">pic.html</a> </body></html>
将工程发布到tomcat中,键入http://localhost:8080/day18FilterNoCache/nocache/pic.html ,可以看到页面有1.jpg
再将pic.html中改为2.jpg,并重新发布,然后在浏览器中按超链接(注意不要刷新),再点击超链接,可以看到pic.html中显示的内容没有变化,原因:图片缓存了
解决办法:
第一步、pic.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>pic.html</title> </head> <body> <img src="./2.jpg"/> <br/> <a href="./test.jsp">test.jsp</a> </body></html>
第二步、test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> </head> <body> <a href="./pic.html">pic.html</a> </body></html>
第三步、过滤器
package cn.itcast.filter;import *;public class NoCacheFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res=(HttpServletResponse)response; res.setDateHeader("Expires",-1); res.setHeader("Cache-Control","no-cache"); res.setHeader("Pragma","no-cache"); chain.doFilter(request, response); } public void destroy() { // TODO Auto-generated method stub }}
第四步、web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app…… <filter> <filter-name>NoCacheFilter</filter-name> <filter-class>cn.itcast.filter.NoCacheFilter</filter-class> </filter> <filter-mapping> <filter-name>NoCacheFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
Filter串联二:
* 若有多个 Filter 程序对某个 Servlet 程序的访问过程进行拦截,当针对该 Servlet 的访问请求到达时,web 容器将把这多个 Filter 程序组合成一个 Filter 链(过滤器链)。Filter 链中各个 Filter 的拦截顺序与它们在应用程序的 web.xml 中映射的顺序(即filter-mapping的顺序)一致
Servlet过滤器对请求的过滤:
A、 Servlet容器创建一个过滤器实例
B、 Servlet容器调用init方法,读取过滤器的初始化参数
C、 Servlet容器调用doFilter方法,根据初始化参数的值,判断该请求是否合法
D、 如果该请求不合法则阻塞该请求
E、 如果该请求合法则调用chain.doFliter方法将该请求向后续传递
例6、检测用户是否登录。
第一种、利用session来做
第一步、login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">…… <form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post"> <div id="input"> <div> 用户:<input type="text" name="username"/><br/></div> <div> 密码:<input type="password" name="password"/><br/></div> </div> <div id="btn"> <input type="submit" value="登录"/> <input type="button" value="注册" onclick=""/> ……
第二步、success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">…… <body> 转发成功!!! <br><a href="${pageContext.request.contextPath}/success1.jsp">success1.jsp</a><br/><a href="${pageContext.request.contextPath}/success2.jsp">success2.jsp</a><br/><a href="${pageContext.request.contextPath}/success3.jsp">success3.jsp</a><br/><a href="${pageContext.request.contextPath}/success4.jsp">success4.jsp</a><br/>……
第三步、LoginServlet.java
package cn.itcast.web;import *;public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); HttpSession session=request.getSession(); //获取用户名 String username=request.getParameter("username"); session.setAttribute("username", username); //转发到success.jsp request.getRequestDispatcher("/success.jsp").forward(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
第四步、success1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>My JSP 'success1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <% String username = (String)session.getAttribute("username"); if(username==null){//表示用户没有登录 String contextPath=request.getContextPath(); //重新定向到login.jsp登陆页面 response.sendRedirect(contextPath+"/login.jsp"); } %> success1.jsp <a href="${pageContext.request.contextPath}/success.jsp">success.jsp</a> </body></html>
第五步、success2.jsp、success3jsp、success4.jsp
第六步、观察结果:在IE中键入:http://localhost:8080/day18CheckLogin/login.jsp 输入用户名登陆 在点击超链接 success1.jsp会看到success1.jsp中的页面内容success1.jsp success.jsp 然后关闭浏览器,在打开一个浏览器,直接键入:
http://localhost:8080/day18CheckLogin/success1.jsp 则页面会转向到login.jsp
第二种方法:过滤器
第一步、配置web.xml
……
<!-- 保存的关键字 --><context-param> <param-name>checkSessionKey</param-name> <param-value>username</param-value></context-param><!-- 重定向的页面 --><context-param> <param-name>redirectURL</param-name> <param-value>/login.jsp</param-value></context-param><!-- 不做检查的列表 --><context-param> <param-name>notCheckURLList</param-name> <param-value>/login.jsp,/servlet/LoginServlet</param-value></context-param><!-- 配置检查用户登录的过滤器 --> <filter> <filter-name>CheckLoginFilter</filter-name> <filter-class>cn.itcast.filter.CheckLoginFilter</filter-class> </filter> <filter-mapping> <filter-name>CheckLoginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
……
第二步、login.jsp
……
<div id="form"> <form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post"> <div id="input"> <div> 用户:<input type="text" name="username"/><br/></div> <div> 密码:<input type="password" name="password"/><br/></div> </div> <div id="btn"> <input type="submit" value="登录"/>
……
第三步、success.jsp
第四步、success1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> </head> <body> success1.jsp <a href="${pageContext.request.contextPath}/success.jsp">success.jsp</a> </body></html>
第五步、LoginServlet.java
package cn.itcast.web;import *;public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws Exception { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); HttpSession session=request.getSession(); //获取用户名 String username=request.getParameter("username"); /*<!-- 保存的关键字 --> <context-param> <param-name>checkSessionKey</param-name> <param-value>username</param-value> </context-param> * */ ServletContext sc=this.getServletContext(); String checkSessionKey = sc.getInitParameter("checkSessionKey"); if(checkSessionKey!=null){ //保存用户名到Session中 session.setAttribute(checkSessionKey, username); } session.setAttribute("username", username); //转发到success.jsp request.getRequestDispatcher("/success.jsp").forward(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
第六步、
package cn.itcast.filter;import *;public class CheckLoginFilter implements Filter { private String checkSessionKey; private String redirectURL; private List notCheckURLList; public void init(FilterConfig filterConfig) throws ServletException { //读取web.xml文件中的初始化参数 /* * <!-- 保存的关键字 --> <context-param> <param-name>checkSessionKey</param-name> <param-value>username</param-value> </context-param> */ ServletContext sc=filterConfig.getServletContext(); checkSessionKey=sc.getInitParameter("checkSessionKey"); this.checkSessionKey=checkSessionKey; /* * <!-- 重定向的页面 --> <context-param> <param-name>redirectURL</param-name> <param-value>/login.jsp</param-value> </context-param> */ redirectURL = sc.getInitParameter("redirectURL"); this.redirectURL=redirectURL; /* * <!-- 不做检查的列表 --> <context-param> <param-name>notCheckURLList</param-name> <param-value>/login.jsp,/servlet/LoginServlet</param-value> </context-param> */ String[] notCheckURLListstr=sc.getInitParameter("notCheckURLList").split(","); notCheckURLList=Arrays.asList(notCheckURLListstr); this.notCheckURLList=notCheckURLList; } public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws Exception { HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; //获取servlet的路径 String servletPath=req.getServletPath(); System.out.println(servletPath); //获取session HttpSession session=req.getSession(); //1.如果访问的路径中包含notCheckURLList中的路径,放行 if(this.notCheckURLList!=null&&this.notCheckURLList.contains(servletPath)){ chain.doFilter(request, response); }else{//2.如果访问路径中不包含notCheckURLList中的路径 //2.1从session中回去用户名 String username=(String)session.getAttribute(this.checkSessionKey); //2.1.1如果用户名不为空,放行 if(username!=null){ chain.doFilter(request, response); }else{ //2.1.2如果用户名为空,重定向到redirectURL指向的登录页面 String contextPath=req.getContextPath(); res.sendRedirect(contextPath+this.redirectURL); } } } public void destroy() { }}
第七步、观察结果:在IE中键入:http://localhost:8080/day18CheckLogin/login.jsp 输入用户名登陆 在点击超链接 success1.jsp会看到success1.jsp中的页面内容success1.jsp success.jsp 然后关闭浏览器,在打开一个浏览器,直接键入:
http://localhost:8080/day18CheckLogin/success1.jsp 则页面会转向到login.jsp
破坏情况(新开一个浏览器)
装饰模式
案例:
1、IMessageBoard.java
package cn.itcast.test;public interface IMessageBoard { public String filter();}
- MessageBoard.java
package cn.itcast.test;public class MessageBoard implements IMessageBoard { @Override public String filter() { return "你喜欢战争吗?"; }}
3.Client.java
package cn.itcast.client;import cn.itcast.test.IMessageBoard;import cn.itcast.test.MessageBoard;public class Client { public static void main(String[] args) { Client c=new Client(); IMessageBoard messageBoard = new MessageBoard(); c.test(messageBoard); } public void test(IMessageBoard messageBoard) { System.out.println(messageBoard); String content = messageBoard.filter(); System.out.println("content"+content); }}
运行结果:cn.itcast.test.MessageBoard@1fc4bec
content你喜欢战争吗?
?要求:在不改变MessageBoard类和Client类中的test方法的代码的情况下输出你喜欢和平吗,如何解决?
方法一、可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性。
第一步、新建一个类MessageBoardExtends.java
package cn.itcast.test;public class MessageBoardExtends extends MessageBoard{ @Override public String filter() { String content=super.filter(); System.out.println("MessageBoardExtends"+content); return content.replaceAll("战争", "和平"); }}
第二步、更新Client.java
package cn.itcast.client;import *;public class Client { public static void main(String[] args) { Client c=new Client(); IMessageBoard messageBoard = new MessageBoardExtends(); c.test(messageBoard); } public void test(IMessageBoard messageBoard) { System.out.println("messageBoard"+messageBoard); String content = messageBoard.filter(); System.out.println("content"+content); }}
第三步、运行结果为:
messageBoardcn.itcast.test.MessageBoardExtends@dc8569MessageBoardExtends你喜欢战争吗?content你喜欢和平吗?
方法二、使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机,Decorator提供了”即插即用”的方法,在运行期间决定何时增加何种功能
第一步、MessageBoardDecorator.java (具体装饰角色,需要一个具体构建角色的类的对象)
package cn.itcast.test;public class MessageBoardDecorator implements IMessageBoard{ private IMessageBoard messageBoard; /** * * @param messageBoard是接口实现类的兑现个,在这个程序中 new MessageBoard */ public MessageBoardDecorator(IMessageBoard messageBoard){ System.out.println("包装类的对象 "+messageBoard); this.messageBoard=messageBoard; } @Override public String filter() { String content = messageBoard.filter(); return content.replaceAll("战争", "和平"); }}
第二步、Client.java
package cn.itcast.client;import *;public class Client { public static void main(String[] args) { Client c=new Client(); //不可变的类 MessageBoard m=new MessageBoard(); IMessageBoard messageBoard = new MessageBoardDecorator(m); c.test(messageBoard); } public void test(IMessageBoard messageBoard) { System.out.println("messageBoard "+messageBoard); String content = messageBoard.filter(); System.out.println("客户端content"+content); }}
第三步、观察结果
包装类的对象 cn.itcast.test.MessageBoard@1bab50a
messageBoard cn.itcast.test.MessageBoardDecorator@c3c749
客户端content你喜欢和平吗?
Decorator定义:
动态给一个对象添加一些额外的职责,就像在墙上刷油漆。使用Decorator模式相比用生成子类方式达到功能的扩展显得更为灵活。
1、抽象构建角色(Component):定义一个抽象接口,以规范准备接受附加责任的对象。
*具体构建角色,具体装饰角色要实现这个接口—Person(抽象类)
2、具体构建角色(Concrete Component):这是被装饰着,定义一个将要被装饰增加功能的类。
*具体构建角色 实现抽象构建角色这个接口 —西施
3、具体装饰角色(Concrete Decorator):负责给构件添加增加的功能。
*具体装饰角色 要实现 抽象构建角色这个接口 —东施
*增加一个构造方法,参数为抽象构建角色类型,接收不能改变类的对象(西施)
*实现filter这个接口
*获取具体构建角色中的内容 —-西施
*增加新的要求 —-打扮西施
例7、为论坛过滤掉不雅文字。
第一步、content.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> </head> <body> 留言板:${content} <form action="${pageContext.request.contextPath}/servlet/ContentServlet" method="post"> <input type="text" name="content"> <input type="submit" value="留言"> </form> </body></html>
第二步、过滤器IlleagleFilter.java
package cn.itcast.filter;import *;public class IlleagleFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { MyHttpServletRequestWrapper httpServletRequestWrapper= new MyHttpServletRequestWrapper((HttpServletRequest)request); chain.doFilter(httpServletRequestWrapper, response); } public void destroy() { }}
第三步、web.xml
<filter> <filter-name>IlleagleFilter</filter-name> <filter-class>cn.itcast.filter.IlleagleFilter</filter-class></filter><filter-mapping> <filter-name>IlleagleFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
第四步、ContentServlet.java
package cn.itcast.web;import *;public class ContentServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String content=request.getParameter("content"); request.setAttribute("content", content); request.getRequestDispatcher("/content.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
第五步、filter.properties
a1=bad1a2=bad2a3=bad3
第六步、MyHttpServletRequestWrapper.java
package cn.itcast.filter;import *;public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{ private static List list=null; public MyHttpServletRequestWrapper(HttpServletRequest request){ super(request); } static{ InputStream ins=MyHttpServletRequestWrapper.class.getResourceAsStream("filter.properties"); Properties prop=new Properties(); try{ prop.load(ins); /* * a1=bad1 * a2=bad2 * a3=bad3 */ Collection c=prop.values(); list=new ArrayList(c); }catch(Exception e){ e.printStackTrace(); } } /** * 重写该方法,在ContentServlet中调用的就是getParameter方法 */ @Override public String getParameter(String name) { //获取的值 String str=super.getRequest().getParameter(name); //包含 更改 if(list!=null){ for(int i=0;i<list.size();i++){ if(str.contains((String)list.get(i))){ str=str.replaceAll((String)list.get(i), "*****************"); } } } return str; }}
第七步、在IE中键入http://localhost:8080/day18IlleagleFilter/content.jsp 加入留言内容
即可看到效果。
- javaee学习之路(六)Servlet过滤器
- JavaEE学习之过滤器 Filter
- JavaEE学习之路-Servlet Lifecycle
- javaee学习之路(七)Servlet监听器
- javaee学习日记之Servlet,过滤器,拦截器,jstl,EL,jsp
- JavaEE学习笔记之Servlet
- 传智播客学习之Servlet过滤器
- JavaEE学习之路-Creating and Initializing a Servlet
- javaee学习之路(四)Servlet编程入门
- JavaEE学习之路|我的第一个servlet
- javaee之过滤器
- JavaEE学习笔记之Servlet/JSP(2)
- JavaEE学习笔记之Servlet/JSP(3)
- JavaEE学习笔记之Servlet/JSP(4)
- JavaEE学习笔记之Servlet/JSP(5)
- JavaEE学习笔记之Servlet/JSP(6)
- JavaEE学习之路
- JavaWeb学习篇之----Servlet过滤器Filter
- 字符内存大小
- XCode
- Python 笔记2
- Web Scraping With Scrapy and MongoDB
- autoconf和automake的使用教程
- javaee学习之路(六)Servlet过滤器
- abstract类和abstract方法
- llibevent2笔记(linux、windows、android的编译和HTTP client应用)
- Android 网络通信HttpClient的环境配置和注意点
- Device driver development manual simplified version
- Java 线程学习笔记(锁、同步等)
- POJ 3260 The Fewest Coins(混合背包+鸽巢原理)
- 技术前沿(解读)
- 用Xlib库进行基本图形编程