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();}
  1. 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 加入留言内容
即可看到效果。

0 0