JSFとUnified EL
続いて、JSP 2.1から導入された式言語であるUnified Expression Languageを試してみよう。JSP 2.0の式言語では、リスト17でも使っているように${list}や${item.id}というような式で変数の値を参照することができた。
リスト17 JSP 2.0の式言語を使ったitemlist.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP 2.1のテスト</title>
</head>
<body>
<h1>Resource Injection</h1>
<%@page import="java.sql.*,javax.sql.*,javax.naming.*"%>
<%@page import="javax.annotation.Resource"%>
<%@page import="java.util.*"%>
<jsp:declaration>
@Resource(name="sampledatabase")
javax.sql.DataSource datasource;
</jsp:declaration>
<jsp:scriptlet>
List list = new ArrayList();
Connection con = datasource.getConnection();
Statement stat = con.createStatement();
String sql = "select * from item";
ResultSet resultSet = stat.executeQuery(sql);
while(resultSet.next()) {
Map map = new HashMap();
map.put("id", resultSet.getInt("id"));
map.put("name", resultSet.getString("name"));
list.add(map);
}
con.close();
request.setAttribute("list",list);
</jsp:scriptlet>
<table border=\"1\">
<thead><tr><th>ID</th><th>Item</th></tr></thead>
<tbody>
<c:forEach var="item" items="${list}">
<tr><td>${item.id}</td><td>${item.name}</td></tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
一方でJSFでは#{item.id}という式を使用する。この違いにより、JSFとJSPを併用している場合に異なる式が混在するという事態になる。
そこで2つの式言語を統一し、同じ表記が使用できるようにUnified ELが導入された。Unified ELでは${}形式と#{}形式の両方の式を使用することができる。両者の大きな違いは、${}が即時評価であるのに対して#{}は遅延評価である点だ。${}式はJSPページが読み込まれた際に評価されるが、#{}式はJSPのライフサイクルの外で動作することになる。
さて、このUnified ELを使用したJSPページの例をリスト18に示す。これはJSFを使ったWebアプリケーションのためのページで、JSFとJSPのタグが混在しており、JSTLのc:forEachタグの中で#{}式を利用している。
リスト18 Unified ELの使ったitemlistJSF.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP 2.1のテスト</title>
</head>
<body>
<f:view>
<h1><h:outputText value="Unified EL" /></h1>
<h:form id="searchForm">
<h:commandButton id="viewItems" value="表示" action="#{ItemSearch.listItems}" />
</h:form>
<table border=\"1\">
<thead><tr><th>ID</th><th>Item</th></tr></thead>
<tbody>
<c:forEach var="item" items="#{ItemSearch.itemlist}">
<tr><td>
<h:outputText id="id" value="#{item.id}"/>
</td><td>
<h:outputText id="name" value="#{item.name}"/> </br>
</td><tr>
</c:forEach>
</tbody>
</table>
</f:view>
</body>
</html>
以下にサーバ側プログラムと必要な設定ファイルの例を示す。ここは本題ではないので詳細な解説は省略するが、内容は一般的なJSFのアプリケーションで、プロジェクト名は「Tomcat6JSF」としておく。データを格納するJavaBeanとしてリスト19、JSFのManaged Beanとしてリスト20のようなプログラムを用意する。Managed Beanではデータベースから取得したデータをitemlistプロパティに格納する。
リスト19 データ格納用のJavaBean(Item.java)
package sample;
public class Item {
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
リスト20 データベース接続を行うManagedBean(ItemSearch.java)
package sample;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
public class ItemSearch {
private Collection<Item> itemlist = new ArrayList<Item>();
public Collection getItemlist() {
return this.itemlist;
}
public String listItems() {
try {
Connection con = DriverManager.getConnection
("jdbc:derby://localhost:1527/sampledb", "test", "test");
Statement stat = con.createStatement();
String sql = "select * from item";
ResultSet resultSet = stat.executeQuery(sql);
while(resultSet.next()) {
Item item =new Item();
item.setId(resultSet.getInt("id"));
item.setName(resultSet.getString("name"));
itemlist.add(item);
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
return "success";
}
}
Managed Beanを有効にするためのfaces-config.xmlはリスト21のようになる。また、web.xmlはリスト22のようになった。
リスト21 WEB-INF/faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>ItemSearch</managed-bean-name>
<managed-bean-class>sample.ItemSearch</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
リスト22 WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
これらのファイルをデプロイする際の構成は図26のようになる。これをTomcatにデプロイして「http://localhost/Tomcat6JSF/faces/itemlistJSF.jsp」にアクセスすると、図27のように表示される。この画面で[表示]ボタンをクリックすればデータベースからデータを取得できる(図28)。