`

项目中用到的一个小工具类(字符过滤器)

    博客分类:
  • java
 
阅读更多

原文:http://javatar.iteye.com/blog/40188

 

字符串过滤,是比较常用的功能,我的当前项目也有用到。 
如过滤User输入的Html,Js代码等, 
由于过滤需求是可能变动的, 
如客户又要你过滤一些脏词或者为内容中的url自动加上超链接等。 
考虑“开-闭”(OCP)原则, 
我决定使用装饰器(Decorator)模式。 
首先定义Decorator接口: 

Java代码  收藏代码
  1. package com.sanook.hompy.util.filter;  
  2.   
  3. public interface StringFilter {  
  4.   
  5.     public void setNextStringFilter(StringFilter stringFilter); //关联下一装饰器  
  6.   
  7.     public String filter(String source); //处理过滤  
  8. }  



然后用模板方法(Template Method)模式实现一个抽象的过滤器: 
这样可以将相同的实现部分抽象出来。 

Java代码  收藏代码
  1. package com.sanook.hompy.util.filter;  
  2.   
  3. public abstract class AbstractStringFilter implements StringFilter {  
  4.   
  5.     private StringFilter stringFilter;  
  6.   
  7.     public void setNextStringFilter(StringFilter stringFilter) {  
  8.         this.stringFilter = stringFilter;  
  9.     }  
  10.   
  11.     public String filter(String source) {  
  12.         String target = doFilter(source);  
  13.         if (stringFilter == null) {  
  14.             return target;  
  15.         }  
  16.         return stringFilter.filter(target);  
  17.     }  
  18.   
  19.     // 模板抽象方法,传入要处理的string,返回处理完的string  
  20.     // 遵循模板方法doXXX命名方式  
  21.     public abstract String doFilter(String source);   
  22.   
  23. }  



空的实现: 

Java代码  收藏代码
  1. package com.sanook.hompy.util.filter;  
  2.   
  3. public class EmptyFilter extends AbstractStringFilter {  
  4.   
  5.     public String doFilter(String source) {  
  6.         return source;  
  7.     }  
  8.   
  9. }  



下面实现该接口的Html过滤: 

Java代码  收藏代码
  1. package com.sanook.hompy.util.filter;  
  2.   
  3. import org.apache.commons.lang.StringUtils;  
  4.   
  5. public class HtmlFilter extends AbstractStringFilter {  
  6.   
  7.     public String doFilter(String source) {  
  8.         source = StringUtils.replace(source, "<""& lt;");  
  9.         source = StringUtils.replace(source, ">""& gt;");  
  10.         source = StringUtils.replace(source, "&""& amp;");  
  11.         source = StringUtils.replace(source, " ""& nbsp;");  
  12.         source = StringUtils.replace(source, "\"""& #0034;");  
  13.         source = StringUtils.replace(source, "\'""& #0039;");  
  14.         return source;  
  15.     }  
  16.   
  17. }  



由于Decorator是嵌套结构(注:这里只用了前(before)装饰,所以看起来有点像链结构,如有必要,也可以加上后(after)装饰), 
它的调用关系需要组装,所以应该用建造者(Builder)模式或简单工厂模式。 
这里使用简单工厂模式,工厂的获取用单例(Singleton)模式返回 

Java代码  收藏代码
  1. package com.sanook.hompy.util.filter;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.apache.commons.logging.Log;  
  7. import org.apache.commons.logging.LogFactory;  
  8.   
  9. import com.sanook.hompy.util.manager.ConfigureManager;  
  10.   
  11. public class StringFilterFactory {  
  12.   
  13.     private static final Log log = LogFactory.getLog(StringFilterFactory.class);  
  14.   
  15.     private static final StringFilterFactory stringFilterFactory = new StringFilterFactory();  
  16.   
  17.     private Map filterMap = new HashMap();  
  18.   
  19.     private StringFilterFactory() {  
  20.         //ConfigureManager是Hompy项目统一读取配置的类,以多例(Multi-Singleton)模式实现  
  21.         filterMap = ConfigureManager.getInstance("filter").getMap();  
  22.     }  
  23.   
  24.     public static StringFilterFactory getInstance() {  
  25.         return stringFilterFactory;  
  26.     }  
  27.   
  28.     //通过一个以逗号分割的过滤器引用名串,获取过滤器  
  29.     public StringFilter getStringFilterChain(String chain) {  
  30.         if (chain == null || chain.length() == 0) {  
  31.             return new EmptyFilter();  
  32.         }  
  33.   
  34.         if ("all".equalsIgnoreCase(chain)) {  
  35.             return getAllStringFilterChain();  
  36.         }  
  37.   
  38.         String[] filters = chain.split("\\,");  
  39.         return getStringFilterChain(filters);  
  40.     }  
  41.   
  42.     public StringFilter getAllStringFilterChain() {  
  43.         String[] filters = (String[]) filterMap.values().toArray();  
  44.         return getStringFilterChain(filters);  
  45.     }  
  46.   
  47.     public StringFilter getStringFilterChain(String[] filters) {  
  48.         if (filters == null || filters.length == 0) {  
  49.             return new EmptyFilter();  
  50.         }  
  51.   
  52.         StringFilter[] stringFilters = new StringFilter[filters.length];  
  53.         for (int i = filters.length - 1; i >= 0; i--) {  
  54.             stringFilters[i] = getStringFilter(filters[i]);  
  55.             if (i != filters.length - 1) {  
  56.                 stringFilters[i].setNextStringFilter(stringFilters[i + 1]);  
  57.             } else {  
  58.                 stringFilters[i].setNextStringFilter(null);  
  59.             }  
  60.         }  
  61.         return stringFilters[0];  
  62.     }  
  63.   
  64.     public StringFilter getStringFilter(String key) {  
  65.         if (key != null) {  
  66.             try {  
  67.                 //通过类名反射得到过滤器的实例  
  68.                 Class clazz = Class.forName((String) filterMap.get(key));  
  69.                 StringFilter stringFilter = (StringFilter) clazz.newInstance();  
  70.                 return stringFilter;  
  71.             } catch (ClassNotFoundException e) {  
  72.                 e.printStackTrace();  
  73.                 log.warn(e);  
  74.             } catch (InstantiationException e) {  
  75.                 e.printStackTrace();  
  76.                 log.warn(e);  
  77.             } catch (IllegalAccessException e) {  
  78.                 e.printStackTrace();  
  79.                 log.warn(e);  
  80.             }  
  81.         }  
  82.         return new EmptyFilter();  
  83.     }  
  84. }  



配置文件filter.properties如下: 

Java代码  收藏代码
  1. html=com.sanook.hompy.util.filter.HtmlFilter  
  2. url=com.sanook.hompy.util.filter.UrlFilter  
  3. js=com.sanook.hompy.util.filter.JavaScriptFilter  
  4. dirty=com.sanook.hompy.util.filter.DirtyWordFilter  
  5. quote=com.sanook.hompy.util.filter.QuotationMarkFilter  
  6. line=com.sanook.hompy.util.filter.NewLineFilter  
  7. lower=com.sanook.hompy.util.filter.LowerFilter  


这些配置将通过ConfigureManager读到filterMap中, 
其中key作为chain的引用名,value为过滤器对象名。 

调用方式: 

Java代码  收藏代码
  1. String chain = "html,js,dirty";  
  2. StringFilter stringFilter = StringFilterFactory.getInstance().getStringFilterChain(chain);  
  3. String source = "<b>aaaa</b>";  
  4. String result = stringFilter.filter(source);  



现在如果你要扩展一个过滤器,只要继承AbstractStringFilter,实现doFilter(String source)方法, 
在filter.properties加入其引用名即可。上面的配置示例中就是Hompy项目用到的一些过滤器。 

Hompy项目以JSP作为View层,而StringFiler是属于展示逻辑,应由View层控制,所以,我使用了自定义标签。 

Java代码  收藏代码
  1. package com.sanook.hompy.servlet.tag;  
  2.   
  3. import com.sanook.hompy.util.filter.StringFilter;  
  4. import com.sanook.hompy.util.filter.StringFilterFactory;  
  5.   
  6. public class FilterTag extends BodyOutTag {  
  7.   
  8.     private static final long serialVersionUID = 1L;  
  9.   
  10.     private String chain;  
  11.       
  12.     public void setChain(String chain) {  
  13.         this.chain = chain;  
  14.     }  
  15.   
  16.     public String doBody(String body) {  
  17.         StringFilter stringFilter = StringFilterFactory.getInstance()  
  18.                 .getStringFilterChain(chain);  
  19.         return stringFilter.filter(body);  
  20.     }  
  21.   
  22. }  




其父类BodyOutTag是一个抽象类 

Java代码  收藏代码
  1. package com.sanook.hompy.presentation.tag;  
  2.   
  3. import javax.servlet.jsp.JspException;  
  4. import javax.servlet.jsp.JspTagException;  
  5. import javax.servlet.jsp.tagext.BodyTagSupport;  
  6.   
  7. public abstract class BodyOutTag extends BodyTagSupport {  
  8.       
  9.     private String body;  
  10.       
  11.     public BodyOutTag() {  
  12.         super();  
  13.         init();  
  14.     }  
  15.       
  16.     private void init() {  
  17.         body = null;  
  18.     }  
  19.       
  20.     public void setBody(String body) {  
  21.         this.body = body;  
  22.     }  
  23.       
  24.     public int doStartTag() throws JspException {  
  25.         return EVAL_BODY_BUFFERED;  
  26.     }  
  27.       
  28.     public int doEndTag() throws JspException {  
  29.         if (body == null) {  
  30.             if (bodyContent != null && bodyContent.getString() != null) {  
  31.                 body = bodyContent.getString().trim();  
  32.             } else {  
  33.                 body = "";  
  34.             }  
  35.         }  
  36.           
  37.         /*如果继承SimpleTagSupport,则用: 
  38.         if (body == null) { 
  39.             body = ""; 
  40.             JspFragment body = getJspBody(); 
  41.             if (body != null) { 
  42.                 StringWriter writer = new StringWriter(); 
  43.                 body.invoke(writer); 
  44.                 body = writer.toString(); 
  45.             } 
  46.         }*/  
  47.           
  48.         body = doBody(body);  
  49.           
  50.         try {  
  51.             pageContext.getOut().print(body == null ? "" : body);  
  52.         } catch (java.io.IOException ex) {  
  53.             throw new JspTagException(ex.getMessage());  
  54.         }  
  55.         body = null;  
  56.         return EVAL_PAGE;  
  57.     }  
  58.       
  59.     public void release() {  
  60.         super.release();  
  61.         init();  
  62.     }  
  63.       
  64.     public abstract String doBody(String body);  
  65.   
  66. }  



配置/WEB-INF/tld/hompy-string.tld, 
(我将其归纳在string处理namespace内) 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3. <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">  
  4.     <description>hompy string tag library</description>  
  5.     <display-name>string</display-name>  
  6.     <tlib-version>1.0</tlib-version>  
  7.     <short-name>s</short-name>  
  8.     <uri>http://hompy.sanook.com/tag/string</uri>  
  9.     <tag>  
  10.         <description></description>  
  11.         <name>filter</name>  
  12.         <tag-class>com.sanook.hompy.servlet.tag.FilterTag</tag-class>  
  13.         <body-content>JSP</body-content>  
  14.         <attribute>  
  15.             <description>body</description>  
  16.             <name>body</name>  
  17.             <required>false</required>  
  18.             <rtexprvalue>true</rtexprvalue>  
  19.             <type>java.lang.String</type>  
  20.         </attribute>  
  21.         <attribute>  
  22.             <description>filter chain key, separator is ,</description>  
  23.             <name>chain</name>  
  24.             <required>true</required>  
  25.             <rtexprvalue>true</rtexprvalue>  
  26.         </attribute>  
  27.     </tag>  
  28. </taglib>  



在web.xml的适当位置加入: 

Xml代码  收藏代码
  1. <taglib>  
  2.     <taglib-uri>hompy-string</taglib-uri>  
  3.     <taglib-location>/WEB-INF/tld/hompy-string.tld</taglib-location>  
  4. </taglib>  



在jsp页面中使用如下: 

Xml代码  收藏代码
  1. <%@ page language="java" contentType="text/html" pageEncoding="UTF-8" isELIgnored="false"%>  
  2. <%@ taglib uri="hompy-string" prefix="s"%>  
  3. <html>  
  4.     <body>  
  5.         Test Filter: <s:filter chain="html,js,dirty">${picture.title}</s:filter>  
  6.     </body>  
  7. </html>  


 

分享到:
评论

相关推荐

    Android开发之EditText字符串过滤器InputFilter

    总之,Android的EditText字符串过滤器InputFilter是一个强大的工具,它允许开发者定制输入行为,提高应用的数据验证和用户体验。理解并熟练掌握InputFilter的使用,对于Android开发者来说是非常重要的技能之一。

    jsp中的过滤器(含例子)

    总的来说,`JSP`中的过滤器是一个强大的工具,它能够帮助我们处理请求和响应,实现跨页面的通用功能,提升应用程序的安全性和用户体验。在实际开发中,熟练掌握过滤器的使用,将大大提升我们的开发效率和代码质量。

    基于vb6开发的网站过滤器源代码

    在本项目中,可能会有一个Filter类,用于处理过滤逻辑。 三、网站过滤关键技术 1. 关键词匹配:VB6可以使用字符串函数(如InStr、Like等)进行关键词匹配。在过滤器中,需要遍历网页内容,对比预设的过滤关键字...

    yatr:用替换符替换字符串中的任何字符。这可以带有区分大小写检查的标志

    `yatr` 是一个工具,用于在字符串中替换特定字符,具有区分大小写的选项。这个工具的名称可能是 "Yet Another Text Replacer" 的缩写,它提供了与传统文本替换功能不同的可能性,尤其是在处理大量文本或者需要更精细...

    软件工程答辩常见问题总结.doc

    * 使用过滤器来解决乱码问题,可以编写一个过滤器类,例如 `SetCharacterEncodingFilter`。 六、过滤器应用 * 使用过滤器来解决乱码问题,可以编写一个过滤器类,例如 `SetCharacterEncodingFilter`。 * 过滤器...

    为了大三实习,四月份开始复习Java,这是复习完Java web所写的一个简单商城项目.zip

    8. **过滤器和监听器**:在Java Web中,过滤器(Filter)用于拦截请求和响应,实现预处理和后处理功能,如登录验证、字符编码转换等。监听器(Listener)则监听Web应用中特定事件,如session的创建、销毁等。 9. **...

    tomcat跨域cors相关jar包 java-property-utils-1.9.jar,cors-filter-1.7.jar,java-util-1.9

    这是一个包含通用Java工具类的库,可能包含字符串处理、集合操作等实用方法。在处理CORS时,可能用于辅助处理请求或响应,比如构建响应头、解析请求头等。 在Tomcat中实现跨域CORS,通常涉及以下几个步骤: 1. **...

    testIO项目

    Java通过一系列类和接口构建了一个完整的I/O流模型,分为字节流和字符流两大类。字节流处理的数据单位是字节,而字符流处理的是Unicode字符。在字节流中,InputStream和OutputStream是所有输入输出流的基类,分别...

    毕业设计: 心理咨询预约管理系统(javaEE)

    utils.filter过滤器,登录过滤,字符过滤等等 utils.jdbc数据库工具类,配置和得到连接池的连接 utils.mail是邮件模块 utils下的ConfigProperties是读入配置文件,ResultDate和UploadResult分别是请求响应结果和...

    Javaweb网上购物商城自己写的课设,一个简单的网上购物商城,通过这次的简单的项目来加深对Java的理解.zip

    在本项目中,我们探索的是一个基于JavaWeb技术构建的简单网上购物商城。这个课程设计旨在帮助学习者深入理解Java编程语言以及其在Web开发中的应用。以下将详细阐述涉及的知识点: 1. **Servlet与JSP**:作为JavaWeb...

    cors-filter-1.7.jar java-util-1.9.1.jar

    2. **配置web.xml**:在你的应用的`WEB-INF/web.xml`文件中,你需要添加一个新的过滤器定义,如下所示: ```xml &lt;filter-name&gt;CORS &lt;filter-class&gt;com.thetransactioncompany.cors.CORSFilter&lt;/filter-class&gt; ...

    apache commons 开源工具列举

    Apache Commons 是一个由Apache软件基金会维护的Java库集合,它为开发人员提供了大量实用的工具类和组件,极大地简化了常见的编程任务。这个库包含了众多模块,每个模块专注于特定的功能领域,例如字符串处理、数学...

    JavaWeb 完整的新闻项目

    9. **过滤器(Filter)与监听器(Listener)**:在JavaWeb中,过滤器可以对请求和响应进行拦截处理,如字符编码转换、权限验证等;监听器则可以监听Web应用中特定事件,如session的创建、销毁等。 10. **Ajax异步...

    XSSSecurityFilter实战

    "XSSSecurityFilter实战"是一个关于如何预防XSS攻击的实践教程,它涵盖了在Java Web开发中使用自定义过滤器来增强应用的安全性。 首先,我们需要了解XSS攻击的基本原理。XSS通常分为反射型、存储型和DOM型三种类型...

    servlet+jsp实现上传下载文件用到的两个JAR包

    这个库提供了一系列实用工具类,简化了文件、流、字符集、缓冲区、读写器和过滤器等的操作。在文件上传下载中,Commons IO 提供了如文件复制、移动、重命名以及读取文件内容的功能。例如,`FileUtils....

    commons-io-1.3.2.jar

    "commons-io-1.3.2.jar" 是Apache Commons IO库的一个版本,它是一个Java类库,专注于提供各种I/O操作的工具类和实用程序。这个版本是1.3.2,发布于2007年,是为了解决早期Java API在处理输入输出流时的一些不足而...

    net.mindview jar下载

    3. **测试辅助类**:书中可能用到一些专门用于测试的工具类,比如断言工具、模拟对象或者数据生成器。 4. **类型转换工具**:可能包含一些方便的静态方法,用于在不同数据类型之间进行安全转换。 5. **线程和并发*...

    json_lib所需要的包

    1. `commons-collections-3.2.jar`: Apache Commons Collections是Java集合框架的扩展库,提供了各种实用工具类和算法,例如映射、过滤器、比较器等,这些在处理JSON数据时可能会用到。 2. `commons-lang-2.3.jar`:...

    IOS项目实战

    本“iOS项目实战”专注于一个具体的字典应用程序的开发,旨在帮助开发者通过实际操作来深化对iOS编程的理解。下面将详细介绍这个项目的相关知识点。 1. **Swift语言基础**:作为iOS开发的主要编程语言,Swift是本...

    C#做的窗口文件搜索器

    在本文中,我们将深入探讨C#中的输入/输出(IO)流和递归算法在文件搜索中的应用,以及如何构建一个简单的窗口搜索器。 首先,C#中的IO流是处理数据输入和输出的基础工具。IO流可以分为两类:字节流(处理二进制...

Global site tag (gtag.js) - Google Analytics