タグ別アーカイブ: J2EE

JSTL でタグ属性に EL 式を書くとエラー


<c:forEach var=”org” items=”${organizations}”> 〜 </c:forEach>

の ${organization} など, タグの属性に EL 式を書くと

According to TLD or attribute directive in tag file, attribute items does not accept any expressions
(TLD やタグファイルの属性ディレクティヴによると、items 属性では式を使ってはいけないことになってますよ)

と怒られた(メッセージに従って EL 式を外すと通る)。何でだろうと悩んでいたら、
<%@taglib%> の uri によって参照しているバージョンが違うようで

<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

としていたのを

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

に変更したら何事もなく動作した。ちなみに環境は
Apache Tomcat/5.5.9 + Jakarta Standard 1.1 Taglib/1.1.2 で、
JSTL については jstl.jar, standard.jar を WEB-INF/lib に入れたのと、
<%@taglib%> を宣言した以外は何もしていない。
どちらかでしか動作しないと思い込んでいたために気づくのが遅れ、これで
2 時間のロス。

jsp の動的 include について


いつも 静的 include (<%@ include path="foo.jsp"%>)だったが、初めて動的 include (<jsp:include /> を試してみた。
– 静的なものと違い, ローカル変数, メソッド定義, import 構文はそれぞれに独立
– page スコープの属性は互いに参照できない(pageContext の attribute など)
– request スコープ以降のものは参照可能。
なので影響範囲を最小にしつつ参照するには request スコープを使うとよい。
– jsp:param (ex. <jsp:param name=”foo” value=”123″ />)はリクエストパラメータ(request.getParameter(String))になる。
– jsp:include 呼び出しと通常のリクエストとを区別するには request スコープでやり取りするとよさそう。

JSTL と EL の実験


<%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
Set set = new HashSet();
set.add(“foo”);
set.add(“boo”);
set.add(“woo”);
set.add(“goo”);
pageContext.setAttribute(“set”, set);
%>
デフォルトの書き出し:<br>
  <c:out value=”${set}” /><br>
単純な forEach:{<br>
<c:forEach items=”${set}” var=”af”>
  <c:out value=”${af}” /><br>
</c:forEach>
}<br>
末尾を意識した forEach:{<br>
<c:forEach items=”${set}” varStatus=”status” var=”af”>
  <c:out value=”${af}” /><c:if test=”${!status.last}”>,<br></c:if>
</c:forEach>
}<br>

結果は次のとおり

デフォルトの書き出し:
[foo, woo, boo, goo]
単純な forEach:{
foo
woo
boo
goo
}
末尾を意識した forEach:{
foo,
woo,
boo,
goo }

 
参考:
<http://www.kawaz.jp/pukiwiki/?JSTL%2FCore#content_1_1>
– ずんWiki
<http://www.javaroad.jp/servletjsp/index.html#jsp>
– Java の道 (Servlet / JSP)
<http://www.stackasterisk.jp/tech/java/tomcat5th02_01.jsp>
– STACK* – EL式とタグファイル

Web アプリケーションの基礎


いまさらながら。
 
– 最低限の Web アプリケーション
webapps などアプリケーションを格納するディレクトリ(Tomcat 5.x なら conf/server.xml の Server タグ内 Host タグの appBase 属性)の中にあり、かつ WEB-INF ディレクトリを持つディレクトリが Web アプリケーションとみなされる。

 + webapps
 |
 –+ HelloApp
   |
   –+ WEB-INF

ファイルアップロード "multipart/form-data" 処理のときに正しくパラメータを受け取るには


– form タグで ENCTYPE=”multipart/form-data” にすると ServletRequest.getParameter(Sting) 系ではパラメータを解釈できず全く値が渡って来なくなるため、Jakarta Commons FileUpload の org.apache.commons.fileupload.DiskFileUpload.parseRequest(…) 等を使うとよい。

// 適当に書いたコードなのでエラーあるかも。
DiskFileUpload o = new DiskFileUpload();
o.setSizeMax(-1);
o.setSizeThreshold(1024);
o.setRepositoryPath(“/tmp”);
o.setHeaderEncoding(“Windows-31J”);
List list = o.parseRequest(request); // FileItem のリスト
for(Iterator it = list.iterator(); it.hasNext();){
    FileItem param = (FileItem)it.next();
    if(!param.isFormField())
        continue();
    out.println(param.getFieldName() + “: ” + param.getString());
}

<http://www.jajakarta.org/commons/fileupload-1.0/ja/withoutPrimary/org/apache/commons/fileupload/DiskFileUpload.html#parseRequest(javax.servlet.http.HttpServletRequest,%20int,%20long,%20java.lang.String)>
– jajakarta.org: FileUpload API 1.0 (Ja)
<http://jakarta.apache.org/commons/fileupload/apidocs/org/apache/commons/fileupload/DiskFileUpload.html>
– Jakarta 公式: FileUpload API (current ver.)

ServletRequest インスタンスからリクエストされたパラメータのコレクションを抽出する


– サーブレットや JSP からクラスを抽出している際に、パラメータを使っているものを分離しようとして、 POJO に ServletRequest を渡すのはどうかなと思っていたところ、ちゃんとメソッドが提供されていた。
<http://java.sun.com/j2ee/sdk_1.3/ja/techdocs/api/javax/servlet/ServletRequest.html#getParameterMap()>
– ServletRequest#getParameterMap()

戻り値:
キーとしてパラメータ名、マップ値としてパラメータ値が格納された不変の java.util.Map。パラメータマップ内のキーは String 型。パラメータマップ内の値は String の配列型

たとえば次のコードが書かれたページ(test)にリクエストを送るとする:

// Arrays.toString(String[]) を利用しているため JDK5.0 以上でしか動かない。
out.println(“<table>”);
for(Iterator it = request.getParameterMap().entrySet().iterator(); it.hasNext();){
        Map.Entry entry = (Map.Entry) it.next();
        out.println(“<tr><td>”+entry.getKey()+”</td><td>”+Arrays.toString((String[])entry.getValue())+”</td></tr>”);
}
out.println(“</table>”);

結果は次の通り:

test?a=foo:
   a [foo]
test?a&b=boo&b=woo
   a []
   b [boo, woo]

JSTL インストール


JSTL は標準で tld が組み込まれているのか、一般の taglib と違って web.xml で uri と tld を結びつける必要がない。手順はたとえば次の通り。
– Jakarta.org の実装をダウンロード(バージョンに注意)
– lib の中身(standard.jar, jstl.jar)を WEB-INF/lib 等パスの通る場所に置く。
– JSTL を使いたい JSP コードで次のようにする。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

– tld 指定しなくても動く、という説明を勘違いして、少しはまってしまった。
http://www.fk.urban.ne.jp/home/kishida/kouza/kishou/jspjstl.html
– Kishida’s SITE – JSTL
http://mecha.peko.to/sjc-wc/index.php?JSP%2FJSTL%2Fcore#content_1_9
– SJC-WC まとめサイト – JSP/JSTL/core
http://www.javaroad.jp/servletjsp/sj_jsp13.htm
– Java の道 – JSP(カスタムタグ)