- 浏览: 1704512 次
- 性别:
- 来自: 杭州699号
文章分类
最新评论
-
莫莫摸:
为什么不用dubbo
RCP数据传输模型回顾 -
大胡子爸爸:
String, Class 都实现了Serializable接 ...
RPC框架几行代码就够了 -
lss598018587:
谢谢大神分享,比起新手看复杂的dubbo框架还不如看大神的这一 ...
RPC框架几行代码就够了 -
15606915740:
你好,请问一下。<dubbo:consumer filt ...
Dubbo文档 -
joqk12345:
...
一些设计上的基本常识
字符串过滤,是比较常用的功能,我的当前项目也有用到。
如过滤User输入的Html,Js代码等,
由于过滤需求是可能变动的,
如客户又要你过滤一些脏词或者为内容中的url自动加上超链接等。
考虑“开-闭”(OCP)原则,
我决定使用装饰器(Decorator)模式。
首先定义Decorator接口:
然后用模板方法(Template Method)模式实现一个抽象的过滤器:
这样可以将相同的实现部分抽象出来。
空的实现:
下面实现该接口的Html过滤:
由于Decorator是嵌套结构(注:这里只用了前(before)装饰,所以看起来有点像链结构,如有必要,也可以加上后(after)装饰),
它的调用关系需要组装,所以应该用建造者(Builder)模式或简单工厂模式。
这里使用简单工厂模式,工厂的获取用单例(Singleton)模式返回
配置文件filter.properties如下:
这些配置将通过ConfigureManager读到filterMap中,
其中key作为chain的引用名,value为过滤器对象名。
调用方式:
现在如果你要扩展一个过滤器,只要继承AbstractStringFilter,实现doFilter(String source)方法,
在filter.properties加入其引用名即可。上面的配置示例中就是Hompy项目用到的一些过滤器。
Hompy项目以JSP作为View层,而StringFiler是属于展示逻辑,应由View层控制,所以,我使用了自定义标签。
其父类BodyOutTag是一个抽象类
配置/WEB-INF/tld/hompy-string.tld,
(我将其归纳在string处理namespace内)
在web.xml的适当位置加入:
在jsp页面中使用如下:
希望各位 帮忙重构。
Like Refactor!
如过滤User输入的Html,Js代码等,
由于过滤需求是可能变动的,
如客户又要你过滤一些脏词或者为内容中的url自动加上超链接等。
考虑“开-闭”(OCP)原则,
我决定使用装饰器(Decorator)模式。
首先定义Decorator接口:
package com.sanook.hompy.util.filter; public interface StringFilter { public void setNextStringFilter(StringFilter stringFilter); //关联下一装饰器 public String filter(String source); //处理过滤 }
然后用模板方法(Template Method)模式实现一个抽象的过滤器:
这样可以将相同的实现部分抽象出来。
package com.sanook.hompy.util.filter; public abstract class AbstractStringFilter implements StringFilter { private StringFilter stringFilter; public void setNextStringFilter(StringFilter stringFilter) { this.stringFilter = stringFilter; } public String filter(String source) { String target = doFilter(source); if (stringFilter == null) { return target; } return stringFilter.filter(target); } // 模板抽象方法,传入要处理的string,返回处理完的string // 遵循模板方法doXXX命名方式 public abstract String doFilter(String source); }
空的实现:
package com.sanook.hompy.util.filter; public class EmptyFilter extends AbstractStringFilter { public String doFilter(String source) { return source; } }
下面实现该接口的Html过滤:
package com.sanook.hompy.util.filter; import org.apache.commons.lang.StringUtils; public class HtmlFilter extends AbstractStringFilter { public String doFilter(String source) { source = StringUtils.replace(source, "<", "& lt;"); source = StringUtils.replace(source, ">", "& gt;"); source = StringUtils.replace(source, "&", "& amp;"); source = StringUtils.replace(source, " ", "& nbsp;"); source = StringUtils.replace(source, "\"", "& #0034;"); source = StringUtils.replace(source, "\'", "& #0039;"); return source; } }
由于Decorator是嵌套结构(注:这里只用了前(before)装饰,所以看起来有点像链结构,如有必要,也可以加上后(after)装饰),
它的调用关系需要组装,所以应该用建造者(Builder)模式或简单工厂模式。
这里使用简单工厂模式,工厂的获取用单例(Singleton)模式返回
package com.sanook.hompy.util.filter; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sanook.hompy.util.manager.ConfigureManager; public class StringFilterFactory { private static final Log log = LogFactory.getLog(StringFilterFactory.class); private static final StringFilterFactory stringFilterFactory = new StringFilterFactory(); private Map filterMap = new HashMap(); private StringFilterFactory() { //ConfigureManager是Hompy项目统一读取配置的类,以多例(Multi-Singleton)模式实现 filterMap = ConfigureManager.getInstance("filter").getMap(); } public static StringFilterFactory getInstance() { return stringFilterFactory; } //通过一个以逗号分割的过滤器引用名串,获取过滤器 public StringFilter getStringFilterChain(String chain) { if (chain == null || chain.length() == 0) { return new EmptyFilter(); } if ("all".equalsIgnoreCase(chain)) { return getAllStringFilterChain(); } String[] filters = chain.split("\\,"); return getStringFilterChain(filters); } public StringFilter getAllStringFilterChain() { String[] filters = (String[]) filterMap.values().toArray(); return getStringFilterChain(filters); } public StringFilter getStringFilterChain(String[] filters) { if (filters == null || filters.length == 0) { return new EmptyFilter(); } StringFilter[] stringFilters = new StringFilter[filters.length]; for (int i = filters.length - 1; i >= 0; i--) { stringFilters[i] = getStringFilter(filters[i]); if (i != filters.length - 1) { stringFilters[i].setNextStringFilter(stringFilters[i + 1]); } else { stringFilters[i].setNextStringFilter(null); } } return stringFilters[0]; } public StringFilter getStringFilter(String key) { if (key != null) { try { //通过类名反射得到过滤器的实例 Class clazz = Class.forName((String) filterMap.get(key)); StringFilter stringFilter = (StringFilter) clazz.newInstance(); return stringFilter; } catch (ClassNotFoundException e) { e.printStackTrace(); log.warn(e); } catch (InstantiationException e) { e.printStackTrace(); log.warn(e); } catch (IllegalAccessException e) { e.printStackTrace(); log.warn(e); } } return new EmptyFilter(); } }
配置文件filter.properties如下:
html=com.sanook.hompy.util.filter.HtmlFilter url=com.sanook.hompy.util.filter.UrlFilter js=com.sanook.hompy.util.filter.JavaScriptFilter dirty=com.sanook.hompy.util.filter.DirtyWordFilter quote=com.sanook.hompy.util.filter.QuotationMarkFilter line=com.sanook.hompy.util.filter.NewLineFilter lower=com.sanook.hompy.util.filter.LowerFilter
这些配置将通过ConfigureManager读到filterMap中,
其中key作为chain的引用名,value为过滤器对象名。
调用方式:
String chain = "html,js,dirty"; StringFilter stringFilter = StringFilterFactory.getInstance().getStringFilterChain(chain); String source = "<b>aaaa</b>"; String result = stringFilter.filter(source);
现在如果你要扩展一个过滤器,只要继承AbstractStringFilter,实现doFilter(String source)方法,
在filter.properties加入其引用名即可。上面的配置示例中就是Hompy项目用到的一些过滤器。
Hompy项目以JSP作为View层,而StringFiler是属于展示逻辑,应由View层控制,所以,我使用了自定义标签。
package com.sanook.hompy.servlet.tag; import com.sanook.hompy.util.filter.StringFilter; import com.sanook.hompy.util.filter.StringFilterFactory; public class FilterTag extends BodyOutTag { private static final long serialVersionUID = 1L; private String chain; public void setChain(String chain) { this.chain = chain; } public String doBody(String body) { StringFilter stringFilter = StringFilterFactory.getInstance() .getStringFilterChain(chain); return stringFilter.filter(body); } }
其父类BodyOutTag是一个抽象类
package com.sanook.hompy.presentation.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.tagext.BodyTagSupport; public abstract class BodyOutTag extends BodyTagSupport { private String body; public BodyOutTag() { super(); init(); } private void init() { body = null; } public void setBody(String body) { this.body = body; } public int doStartTag() throws JspException { return EVAL_BODY_BUFFERED; } public int doEndTag() throws JspException { if (body == null) { if (bodyContent != null && bodyContent.getString() != null) { body = bodyContent.getString().trim(); } else { body = ""; } } /*如果继承SimpleTagSupport,则用: if (body == null) { body = ""; JspFragment body = getJspBody(); if (body != null) { StringWriter writer = new StringWriter(); body.invoke(writer); body = writer.toString(); } }*/ body = doBody(body); try { pageContext.getOut().print(body == null ? "" : body); } catch (java.io.IOException ex) { throw new JspTagException(ex.getMessage()); } body = null; return EVAL_PAGE; } public void release() { super.release(); init(); } public abstract String doBody(String body); }
配置/WEB-INF/tld/hompy-string.tld,
(我将其归纳在string处理namespace内)
<?xml version="1.0" encoding="UTF-8" ?> <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"> <description>hompy string tag library</description> <display-name>string</display-name> <tlib-version>1.0</tlib-version> <short-name>s</short-name> <uri>http://hompy.sanook.com/tag/string</uri> <tag> <description></description> <name>filter</name> <tag-class>com.sanook.hompy.servlet.tag.FilterTag</tag-class> <body-content>JSP</body-content> <attribute> <description>body</description> <name>body</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>java.lang.String</type> </attribute> <attribute> <description>filter chain key, separator is ,</description> <name>chain</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
在web.xml的适当位置加入:
<taglib> <taglib-uri>hompy-string</taglib-uri> <taglib-location>/WEB-INF/tld/hompy-string.tld</taglib-location> </taglib>
在jsp页面中使用如下:
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8" isELIgnored="false"%> <%@ taglib uri="hompy-string" prefix="s"%> <html> <body> Test Filter: <s:filter chain="html,js,dirty">${picture.title}</s:filter> </body> </html>
希望各位 帮忙重构。
Like Refactor!
评论
3 楼
wwicked
2017-07-14
2 楼
CheungCharles
2016-01-05
1 楼
leisure
2006-12-30
Jive论坛中的过滤功能是采用的也是装饰器(Decorator)模式.可以参考
发表评论
-
能力成长模型
2012-05-09 00:28 23013最近看了温伯格1986年出版的《技术领导之路》, 很老的书,讲 ... -
以HTTL为例讲讲模块分包&领域模型&扩展框架
2011-10-09 20:08 16814注:该博客内容已加入 ... -
使用Map参数的Webx3扩展
2011-08-28 02:10 5934因Webx3是开源的,所以把这个简单的Webx3扩展发在博客上 ... -
Netty内存泄露
2011-08-02 20:09 24979转于自己在公司的Blog: ... -
Grizzly和Netty以及Mina简单性能对比
2011-07-17 02:48 29767转于自己在公司的Blog: http://pt.alibaba ... -
RPC框架几行代码就够了
2011-07-14 00:34 90287转于自己在公司的Blog: http://pt.alibaba ... -
魔鬼在细节中
2011-05-24 14:50 32255转于自己在公司的Blog: ... -
Dubbo扩展点重构
2011-05-12 22:09 38913转于自己在公司的Blog: http://pt.alibaba ... -
配置设计
2011-03-09 23:41 23612转于自己在公司的Blog: ... -
[转]HTML5设计原理
2011-03-09 22:57 7839Jeremy Keith在 Fronteers 2010 ... -
Hessian序列化不设SerializerFactory性能问题
2010-12-27 11:38 6490转于自己在公司的Blog: http://pt.alibaba ... -
动态代理方案性能对比
2010-11-17 21:38 46249转于自己在公司的Blog: http://pt.alibaba ... -
防痴呆设计
2010-11-05 18:58 17703转于自己在公司的Blog: ... -
负载均衡扩展接口重构
2010-11-05 18:53 8768转于自己在公司的Blog: ... -
分布式服务框架常被质疑的价值
2010-11-05 18:52 5743转于自己在公司的Blog: http://pt.alibaba ... -
Hessian3.2.1在序列化32.5k字符串时的问题
2010-11-05 18:49 7288转于自己在公司的Blog: http://pt.alibaba ... -
一些设计上的基本常识
2010-07-05 19:28 27803转于自己在公司的Blog: ... -
谈谈扩充式扩展与增量式扩展
2010-06-12 19:46 19427转于自己在公司的Blog: http://pt.alibaba ... -
Scaling Architecture
2010-02-25 10:31 4129Scaling Second Life: http://p ... -
EBay SOA
2010-02-23 18:23 4811EBay SOA PPT
相关推荐
总之,Android的EditText字符串过滤器InputFilter是一个强大的工具,它允许开发者定制输入行为,提高应用的数据验证和用户体验。理解并熟练掌握InputFilter的使用,对于Android开发者来说是非常重要的技能之一。
总的来说,`JSP`中的过滤器是一个强大的工具,它能够帮助我们处理请求和响应,实现跨页面的通用功能,提升应用程序的安全性和用户体验。在实际开发中,熟练掌握过滤器的使用,将大大提升我们的开发效率和代码质量。
在本项目中,可能会有一个Filter类,用于处理过滤逻辑。 三、网站过滤关键技术 1. 关键词匹配:VB6可以使用字符串函数(如InStr、Like等)进行关键词匹配。在过滤器中,需要遍历网页内容,对比预设的过滤关键字...
`yatr` 是一个工具,用于在字符串中替换特定字符,具有区分大小写的选项。这个工具的名称可能是 "Yet Another Text Replacer" 的缩写,它提供了与传统文本替换功能不同的可能性,尤其是在处理大量文本或者需要更精细...
* 使用过滤器来解决乱码问题,可以编写一个过滤器类,例如 `SetCharacterEncodingFilter`。 六、过滤器应用 * 使用过滤器来解决乱码问题,可以编写一个过滤器类,例如 `SetCharacterEncodingFilter`。 * 过滤器...
8. **过滤器和监听器**:在Java Web中,过滤器(Filter)用于拦截请求和响应,实现预处理和后处理功能,如登录验证、字符编码转换等。监听器(Listener)则监听Web应用中特定事件,如session的创建、销毁等。 9. **...
这是一个包含通用Java工具类的库,可能包含字符串处理、集合操作等实用方法。在处理CORS时,可能用于辅助处理请求或响应,比如构建响应头、解析请求头等。 在Tomcat中实现跨域CORS,通常涉及以下几个步骤: 1. **...
Java通过一系列类和接口构建了一个完整的I/O流模型,分为字节流和字符流两大类。字节流处理的数据单位是字节,而字符流处理的是Unicode字符。在字节流中,InputStream和OutputStream是所有输入输出流的基类,分别...
utils.filter过滤器,登录过滤,字符过滤等等 utils.jdbc数据库工具类,配置和得到连接池的连接 utils.mail是邮件模块 utils下的ConfigProperties是读入配置文件,ResultDate和UploadResult分别是请求响应结果和...
在本项目中,我们探索的是一个基于JavaWeb技术构建的简单网上购物商城。这个课程设计旨在帮助学习者深入理解Java编程语言以及其在Web开发中的应用。以下将详细阐述涉及的知识点: 1. **Servlet与JSP**:作为JavaWeb...
2. **配置web.xml**:在你的应用的`WEB-INF/web.xml`文件中,你需要添加一个新的过滤器定义,如下所示: ```xml <filter-name>CORS <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> ...
Apache Commons 是一个由Apache软件基金会维护的Java库集合,它为开发人员提供了大量实用的工具类和组件,极大地简化了常见的编程任务。这个库包含了众多模块,每个模块专注于特定的功能领域,例如字符串处理、数学...
9. **过滤器(Filter)与监听器(Listener)**:在JavaWeb中,过滤器可以对请求和响应进行拦截处理,如字符编码转换、权限验证等;监听器则可以监听Web应用中特定事件,如session的创建、销毁等。 10. **Ajax异步...
"XSSSecurityFilter实战"是一个关于如何预防XSS攻击的实践教程,它涵盖了在Java Web开发中使用自定义过滤器来增强应用的安全性。 首先,我们需要了解XSS攻击的基本原理。XSS通常分为反射型、存储型和DOM型三种类型...
这个库提供了一系列实用工具类,简化了文件、流、字符集、缓冲区、读写器和过滤器等的操作。在文件上传下载中,Commons IO 提供了如文件复制、移动、重命名以及读取文件内容的功能。例如,`FileUtils....
"commons-io-1.3.2.jar" 是Apache Commons IO库的一个版本,它是一个Java类库,专注于提供各种I/O操作的工具类和实用程序。这个版本是1.3.2,发布于2007年,是为了解决早期Java API在处理输入输出流时的一些不足而...
3. **测试辅助类**:书中可能用到一些专门用于测试的工具类,比如断言工具、模拟对象或者数据生成器。 4. **类型转换工具**:可能包含一些方便的静态方法,用于在不同数据类型之间进行安全转换。 5. **线程和并发*...
1. `commons-collections-3.2.jar`: Apache Commons Collections是Java集合框架的扩展库,提供了各种实用工具类和算法,例如映射、过滤器、比较器等,这些在处理JSON数据时可能会用到。 2. `commons-lang-2.3.jar`:...
本“iOS项目实战”专注于一个具体的字典应用程序的开发,旨在帮助开发者通过实际操作来深化对iOS编程的理解。下面将详细介绍这个项目的相关知识点。 1. **Swift语言基础**:作为iOS开发的主要编程语言,Swift是本...
在本文中,我们将深入探讨C#中的输入/输出(IO)流和递归算法在文件搜索中的应用,以及如何构建一个简单的窗口搜索器。 首先,C#中的IO流是处理数据输入和输出的基础工具。IO流可以分为两类:字节流(处理二进制...