プロジェクトで使用されるガジェットクラス(文字フィルタ)
文字列フィルタリングは、比較的一般的な機能であり、私の現在のプロジェクトでも役立ちます.
User入力のHtml、Jsコードなどをフィルタする、
フィルタ需要が変動する可能性があるため、
お客様が汚い言葉をフィルタリングしたり、コンテンツのurlに自動的にハイパーリンクを付けたりするなどします.
「開閉」(OCP)の原則を考慮し、
デコレータ(Decorator)モードを使うことにしました.
まず、Decoratorインタフェースを定義します.
次に、テンプレートメソッド(Template Method)モードで抽象的なフィルタを実装します.
これにより,同じ実装部分を抽象化することができる.
空の実装:
次に、このインタフェースのHtmlフィルタリングを実現する.
Decoratorはネストされた構造(注:ここでは前(before)の装飾しか使われていないので、チェーン構造のように見えますが、必要に応じて後(after)の装飾を加えることもできます)、
呼び出し関係は組み立てる必要があるので、ビルダーモードまたは単純ファクトリモードを使用する必要があります.
ここでは単純ファクトリモードを用い,ファクトリの取得は単例(Singleton)モードで返す.
プロファイルpropertiesは次のとおりです.
これらの構成は、ConfigureManagerでfilterMapに読み込まれます.
keyはchainの参照名、valueはフィルタオブジェクト名です.
呼び出し方法:
フィルタを拡張するには、AbstractStringFilterを継承し、doFilter(String source)メソッドを実装するだけで、
フィルターでpropertiesはその参照名を加えればよい.上記の構成例では、Hompyプロジェクトで使用されるフィルタの一部です.
HompyプロジェクトはJSPをビューレイヤとしているが、StringFilerはディスプレイロジックに属し、ビューレイヤによって制御されるべきであるため、カスタムラベルを使用した.
親の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)の装飾を加えることもできます)、
呼び出し関係は組み立てる必要があるので、ビルダーモードまたは単純ファクトリモードを使用する必要があります.
ここでは単純ファクトリモードを用い,ファクトリの取得は単例(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();
}
}
プロファイル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)メソッドを実装するだけで、
フィルターでpropertiesはその参照名を加えればよい.上記の構成例では、Hompyプロジェクトで使用されるフィルタの一部です.
HompyプロジェクトはJSPをビューレイヤとしているが、StringFilerはディスプレイロジックに属し、ビューレイヤによって制御されるべきであるため、カスタムラベルを使用した.
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!