はじめに
もっと気軽にEEを実装してみたい! 試してみたい!
ということで、Tomcatで、JSF + CDI を動作させてみたいと思います。
Tomcatでは通常はJSFとCDIは動きませんが、Tomcat9はCDIをサポートしているようなので試してみます。
動作確認用のサンプルアプリは、ログイン画面と、成功時に遷移するトップ画面を作ります。
ざっくり、こんな感じ。
環境は以下のとおりです。
- mac os
- java13
- Eclipse for Enterprise Java Developers (2020-09)
- Tomcat 9.0.39
実装の前に必要なこと
CDIを利用するには、Apache OpenWebBeans
JSFを利用するには、Apache MyFaces
が必要です。
以下のような手順で環境設定していきます。
- Apache OpenWebBeansのzipをダウンロードして解凍
- Apache MyFacesのzipをダウンロード(解凍はしない)
- 1で解凍したフォルダ内でシェルを実行
- web.xmlの設定
1. Apache OpenWebBeansのダウンロード
Apache OpenWebBeansのページからダウンロードします。
今回は、openwebbeans-distribution-2.0.18-binary.zip
をダウンロードしました。
ダウンロード後、解凍します。
2. Apache MyFacesのダウンロード
Apache MyFacesのページからダウンロードします。
今回は、myfaces-core-assembly-2.3-next-M4-bin.zip
をダウンロードしました。
このzipは解凍不要です。このまま利用します。
3.シェルの実行
OpenWebBeansを解凍したフォルダ内にinstall_owb_tomcat7_myfaces.sh
があるので実行します。
引数は、ダウンロードしたmyfacesのzipファイルとTomcatのパスです。
./install_owb_tomcat7_myfaces.sh /ダウンロードパス/myface-core-assembly-2.3-next-M4-bin.zip tomcatのパス
実行すると必要なjarファイルがtomcat/lib
にコピーされ、context.xmlにListenerが追加されます。
4. web.xmlの設定
CDIとJSFを有効にするためListenerを設定します。それとServletのMappingを設定します。
<listener>
<listener-class>org.apache.webbeans.servlet.WebBeansConfigurationListener</listener-class>
</listener>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<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>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
これで準備完了です。TomcatでCDI/JSFが動くようになったはずです!
実装
動作確認のため、サンプルアプリを実装してみます。まずは、mavenの設定です。
mavenの設定
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- JSF -->
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>2.3-next-M4</version>
<scope>provided</scope>
</dependency>
<!-- CDI -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
CDIやJSFのコンパイルを通すためにprovidedで追加します。動作時にはtomcat/libにあるので
不要です。
ついでにlombokも導入しました。(これは必須ではありません)
画面の作成
JSFでは、画面(xhtml)と、画面に対応するBackingBeanを作成します。
まずは画面を作成します。デザインは無視して簡潔に実装します。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ph="http://xmlns.jcp.org/jsf/passthrough"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSFサンプル</title>
</h:head>
<body>
<h:messages escape="true" id="messages" showDetail="false" closable="true"/>
<h:form id="form">
<br/>
<h:inputText value="#{index.loginId}" ph:placeholder="Username" /><br/>
<h:inputSecret value="#{index.password}" ph:placeholder="Password" /><br/>
<h:commandButton action="#{index.loginEvent()}" value="ログイン" update="@form" />
</h:form>
</body>
</html>
- シンプルに項目を配置しただけの画面です。
-
h:messages
はメッセージを表示するエリアです。 - ログインボタンを押すとBackingBeanで定義している
loginEvent
メソッドを実行するようにしています。
次にBackingBeanですね。
@Named("index") // ・・・①
@ViewScoped
@Getter
@Setter
public class IndexBean implements Serializable {
private String loginId; // ・・・②
private String password;
public String loginEvent() {
if (!loginId.isEmpty() && !password.isEmpty()) {
return "top.xhtml?redirect=true"; // ・・・③
} else {
// ・・・④
FacesContext context = FacesContext.getCurrentInstance();
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "認証エラーです", "");
context.addMessage(null, message);
return null;
}
}
}
① Namedアノテーションで、index.xhtmlのEL式から見えるように設定します。
② 画面の項目に合わせて属性を定義します。
③ ログインIDとパスワードの両方になにか入力されていれば、画面遷移するようにしました。
④ それ以外のときは、自画面でメッセージを表示するようにしました。
次に、遷移先のTop画面です。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ph="http://xmlns.jcp.org/jsf/passthrough"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSFサンプル</title>
</h:head>
<body>
<h:form id="form">
<div>TOP画面 </div>
</h:form>
</body>
</html>
完成
メッセージも表示されるし、画面遷移もできました。思ったより簡単でした!
以上です。