復習日記

勤務時間内で理解できなかったことやつまづいたことをまとめていく予定。

JSF2.2を使ってみる

【環境】
Windows8
JDK1.7
Eclipse4.3(Kepler)
WildFly8

JSF(JavaServer Faces)とは】
Webアプリケーションのアーキテクチャ・モデルであるMVC(Model-View-Controller)の「View」に当たる要素を作り上げるためのテクノロジーとのこと。JSPの進化版ってイメージ。

M(モデル):JSFマネージドBean
V(ビュー):Facelets
C(コントローラ):FacesServlet


前回の続きから。JSF2.2を使うのに必要なことは↓の通り。めんどい。。
①POM.xmlに依存ライブラリの記述を追加する
JSF用のfaces-config.xmlをWEB-INF直下に配置する
③WEB-INF直下のweb.xmlにFacesServletの記述を追加する
CDI用のbeans.xmlをWEB-INF直下に配置する
JSFマネージドBeanを作成する
⑥サンプルページを作成する(index.xhtml)

 参考)JSFJavaServer Faces)の基本
    http://d.hatena.ne.jp/tanakakns/20131211/1386757110

【手順】
1.pom.xmlに依存ライブラリを追加。
 不要なライブラリ含めてjboss-javaee-web-7.0をフルセットで追加しちゃいました。
 どれが必要でどれが不要なライブラリかはもう少し知識が増えてから検討したいと思います。

 参考)MavenではじめるJava EE
    http://d.hatena.ne.jp/nekop/20131202/1385965701

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>jp.co.raimus.sample</groupId>
	<artifactId>testJavaEE7</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.jboss.spec</groupId>
				<artifactId>jboss-javaee-web-7.0</artifactId>
				<version>1.0.0.Final</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-embedder</artifactId>
			<version>3.1.0</version>
			<exclusions>
				<exclusion>
					<groupId>*</groupId>
					<artifactId>*</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- External JavaEE spec APIs (not part of the JBoss JavaEE Specs project) -->
		<dependency>
			<groupId>javax.enterprise</groupId>
			<artifactId>cdi-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.1-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- JBoss JavaEE API Specs Projects -->
		<dependency>
			<groupId>org.jboss.spec.javax.annotation</groupId>
			<artifactId>jboss-annotations-api_1.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.ejb</groupId>
			<artifactId>jboss-ejb-api_3.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.el</groupId>
			<artifactId>jboss-el-api_3.0_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.faces</groupId>
			<artifactId>jboss-jsf-api_2.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.interceptor</groupId>
			<artifactId>jboss-interceptors-api_1.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.json</groupId>
			<artifactId>jboss-json-api_1.0_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.resource</groupId>
			<artifactId>jboss-connector-api_1.7_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.servlet</groupId>
			<artifactId>jboss-servlet-api_3.1_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.servlet.jsp</groupId>
			<artifactId>jboss-jsp-api_2.3_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.servlet.jstl</groupId>
			<artifactId>jboss-jstl-api_1.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.transaction</groupId>
			<artifactId>jboss-transaction-api_1.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.websocket</groupId>
			<artifactId>jboss-websocket-api_1.0_spec</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>jaxrs-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.spec.javax.xml.bind</groupId>
			<artifactId>jboss-jaxb-api_2.2_spec</artifactId>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>testJavaEE7</finalName>
		<plugins>
			<!-- Set to compile using JDK 7 -->
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


2.faces_config.xmlをWEB-INF直下に配置。
ちょっと古い記事を見ると以前はfaces-config.xmlにマネージドBeanを登録する必要あったみたいですね。
今は、アノテーションで済むようになった、と。

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
	
</faces-config>

3.web.xmlを編集
JSFのコントローラであるFacesServletの記述を入れてます。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>testJavaEE7</display-name>
  
  <!-- JSF用 -->
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</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>faces/index.xhtml</welcome-file>
  </welcome-file-list>

</web-app>

4.beans.xmlをWEB-INF直下に配置。
CDI1.1からbean-discovery-modeが必須となっていて、"all"じゃなくて、"annotated"が推奨のようです。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
  bean-discovery-mode="annotated">
</beans>

5.JSFマネージドBean(jp.co.raimus.sample.managedbean.SampleManagedBean)
ゲッタ、セッタしかないJavaBeanです。

package jp.co.raimus.sample.managedbean;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named(value = "sampleManagedBean")
@RequestScoped
public class SampleManagedBean {
  
  private String input;
  
  public SampleManagedBean() {
  }
  
  public String pushButton() throws Exception {
    System.out.println(getInput());
    return "";
  }

  public String getInput() {
    return input;
  }

  public void setInput(String input) {
    this.input = input;
  }
}

6.index.xhtml(webapp直下)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="ja" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
  <meta charset="UTF-8" />
  <title>testJavaEE7</title>
</h:head>
<h:body>
  はろー Facelets
  <h:form>
    <h:inputText id="textField" value="#{sampleManagedBean.input}"/>
    <h:commandButton value="Send Message" action="#{sampleManagedBean.pushButton()}"/><br/>
    <h:outputLabel value="#{sampleManagedBean.input}" />
  </h:form>
</h:body>
</html>

7.設定全部終わったのでようやくWildFly起動

初期表示
f:id:raimus0904:20140602005116j:plain

「これがCDI?」と入力
f:id:raimus0904:20140602005459j:plain

outputLabelに"#{sampleManagedBean.input}"が表示された。
f:id:raimus0904:20140602005529j:plain

ちなみに標準出力にも↓のように出てました

00:51:34,580 INFO  [stdout] (default task-8) これがCDI?

次回はもうちょっとJSFの深入りしてみようと思います。