リスト要素を指定の文字で連結するファンクションを自作してみる

JSTLのfn:joinで配列を指定の文字で連結する

JSTLを使って、配列を指定の文字で連結するにはfn:joinを使用します。
fn:joinの引数は、1番目が配列で、2番名が連結文字です。


具体的な使用例はこんな感じ。

<%
String[] fuga = {"aaa", "bbb", "ccc"};
request.setAttribute("fuga",fuga);
%>

${fn:join(fuga, '=')}

結果は「aaa=bbb=ccc」のようになります。

アクションの配列プロパティを指定の文字で連結する(失敗)

同様のことをアクションのプロパティで試してみました。
[Action側]

  public String[] hoge = {"aaa", "bbb", "ccc"};

[JSP側]

  ${fn:join(hoge, '=')}


これは、正しく動作しませんでした。
理由は、以下のSeasar MLのひがさんの説明を参照。

ActionやActionFormのプロパティは、 publicフィールドを ELやStrutsが参照できるようにするために、 JavaBeansはMapに、配列はListにラップされています。 プロパティアクセス(.)や配列アクセス([数値])以外のやり方で、 変数にアクセスするときには気をつけてください。


ドキュメントにも追加しておきました。
http://sastruts.seasar.org/featureReference.html#JSP


なるほど、アクションの配列プロパティはListにラップされる訳かぁ。
では配列ではなくList版のfn:joinがあれば、なんとかなるかも。

リスト要素を指定の文字で連結するファンクションを作ってみる

そんな訳で作ってみました。以下の要領で使うことができます。


[MyJoinAction.java]

public class MyJoinAction {

	public String[] hoge = {"aaa", "bbb", "ccc"}; 
	
	public List<String> fuga = new ArrayList<String>();
	
	@Execute(validator=false)
	public String index() {
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");		
		return "myJoin.jsp";
	}
}


[myJoin.jsp]

<html><body>
${my:join(hoge, '=')}
<br>
${my:join(fuga, '=')}
</body></html>


[myJoin.jspの実行結果]

aaa=bbb=ccc
aaa=bbb=ccc



ちなみに、この機能が欲しいと思った動機は、
前ページから受け取った複数選択チェックボックスの検索条件を
カンマ + 空白区切りで表示させるためでした。
(まじめにゴリゴリやると意外に面倒なんですよねぇ。)

my:joinの作り方

まずは、staticメソッドを持つクラスを作成します。


MyFunctions.java

package tutorial.util;
import java.util.List;

public class MyFunctions {
	
    /**
     * リスト要素を指定の文字で連結します。
     * 
     * @param list
     *            リスト
     * @param separator
     *            連結文字
     * @return 連結した結果
     */
    public static String join(List list, String separator) {
        if (list == null) {
        	return "";        
        }
        if (separator == null) {
        	separator = "";
        }
        
        StringBuffer buf = new StringBuffer();
        for (int i=0; i < list.size(); i++) {
            buf.append(list.get(i));
            if (i < list.size() - 1) {
            	buf.append(separator);
            }
        }
        
        return buf.toString();
    }	
}


次にTLDファイルを作成します。今回は my.tldという名前で作成して、
それを META-INFフォルダの直下に置きました。


my.tld

<?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/web-jsptaglibrary_2_0.xsd"
 version="2.0">
  <tlib-version>2.0</tlib-version>
  
  <function>
    <name>join</name>
    <function-class>tutorial.util.MyFunctions</function-class>
    <function-signature>
    	java.lang.String join(java.util.List, java.lang.String)
    </function-signature>
  </function>
</taglib>

ポイントは、staticメソッドのシグニチャ を定義するところです。


最後に、common.jspに以下の行を追加します。

<%@taglib prefix="my" uri="/META-INF/my.tld" %>


この仕込みをしておけば、JSPファイルから ${my:join(list, ", ")}
のような簡潔な記述でEL式内で自作したstaticメソッドを呼び出し可能です。


一度、ファンクションの仕組みを構築してしまえば、
後からstaticメソッドを追加するのはとっても簡単。


以上