目的
Gradleを使って、JavaServlet 3.1とJSFの組み合わせによるWebアプリの作成に関するノウハウが、ググる先生に聞いても、なかなか出てこないので、断片的な情報をまとめる。
何故、Tomcatなのか?
政治的な理由…
というよりも、Jettyを使うケースは、おそらくTomcatを使うよりも楽なはずなので、Tomcatを選んだ。
といっても、gradleのビルドスクリプトを一部変えるだけで動くはず
何故、Eclipseなのか?
これも政治的な理由。
まぁ、Javaを使った開発のプロジェクトって、大抵がEclipseだから、個人的に使うとかでないと、IntelliJ IDEAとか使えないんだよね〜
ということで、Eclipse。
でも、実際のところ、Eclipseに特化した部分は、1箇所しかないので大丈夫。
何故、JSFなのか?
今時、JavaでHTMLを吐き出すなんてそうはやらないでしょ?
JAX-RSとかでREST API作って、HTMLはJavaScript(altJS系?)とかで、完全に分業するでしょ?作業者が別かは別として…
でないと、クライアントがネイティブアプリの場合にダメでしょ?
というのはおいておいて…
新人君にいきなりJAX-RSでAPI作って、HTMLとかJavaScript書いて…って、流石に酷なので、新人研修でも使えるように、JSFを使って、ソースコードは一緒になろうとも(プロジェクト分けれ一緒にはならないはず)、サクッっと書ける方がいいはず。
少なくとも、JavaScriptを覚えてもらうという部分を分けられる。
前提
以下のアプリがインストールされている環境(バージョンは最新のものを使えばいいはず)
- JDK 8
- Eclipse 4.5
- Gradle 2.9
Gradleプロジェクトの作成
プロジェクト(化したい)のルートディレクトリに入って、以下を実行する。
gradle init
build.gradleの編集
// Apply the java plugin to add support for Java
の前の/
と、最終行の/
を消す。
Servlet APIとJSFを依存関係に追加
dependenciesに、以下を加える。
compile 'org.apache.myfaces.core:myfaces-api:2.2.9'
compile 'org.apache.myfaces.core:myfaces-impl:2.2.9'
compile 'javax.servlet:jstl:1.2'
compile 'org.primefaces:primefaces:5.3'
compile 'javax.servlet:javax.servlet-api:3.1.0'
def tomcatVersion = '8.0.30'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}"
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
Tomcatプラグインの設定を行う
gradle-tomcat-pluginの公式サイトの説明に従い、build.gradleへ、buildscriptやらgradle pluginの設定やら、dependenciesの追加などを行う。
Eclipse関連のお膳立て
Eclipseでなければ、それぞれの環境に合わせてやったりやらなかったりしてください。
build.gradleにEclipseのための設定を追記する
※ {projectName}は、各自のプロジェクト名に読み替えてください
apply plugin: 'eclipse-wtp'
eclipse {
wtp {
facet {
facet name: 'java', version: '1.8'
facet name: 'jst.web', version: '7.0'
}
component {
contextPath = '{projectName}'
}
}
}
Eclipseプロジェクト化
以下を実行する。
gradle eclipse
Eclipseへのインポート
(普通にインポート出来るのでインポートします)
サーブレットのための諸々を追加する
ソースディレクトリの追加
src/main配下にjavaディレクトリとWEB-INFディレクトリを追加する
mkdir -p src/main/java
mkdir -p src/main/webapp/WEB-INF
Eclipseで src/main/javaをsource directoryに追加する
web.xmlの追加
src/main/webapp/WEB-INF配下に以下の内容のweb.xmlを配置する
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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-app_3_1.xsd"
version="3.1">
<!-- JSF mapping -->
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<context-param>
<description>Defines which packages to scan for beans, separated by commas. Necessary for when using tomcat7:run.</description>
<param-name>org.apache.myfaces.annotation.SCAN_PACKAGES</param-name>
<!-- exampleは、各自のパッケージに置き換えてください -->
<param-value>example</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>0</param-value>
</context-param>
<context-param>
<description>
Set the project stage to "Development", "UnitTest", "SystemTest", or "Production".
An optional parameter that makes troubleshooting errors much easier.
You should remove this context parameter before deploying to production!
</description>
<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>
<!-- Map these files with JSF -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
faces-config.xmlの追加
src/main/webapp/WEB-INF配下に以下の内容のfaces-config.xmlを配置する
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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"
version="2.2">
</faces-config>
Managed Beanの追加
任意のパッケージに、任意のクラス名で以下のようなサーブレットを追加します。
ここでは、とりあえず、example.IndexBeanとしています。
package example;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ViewScoped
@ManagedBean
public class IndexBean implements Serializable {
private static final long serialVersionUID = 1L;
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String doAction() {
System.out.println("message at MessageAction#doAction = " + message);
return null;
}
}
index.xhtmlの追加
src/main/webapp配下に以下の内容のindex.xhtmlを配置する
<!DOCTYPE html>
<html template="/WEB-INF/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Top Menu</title>
</h:head>
<h:body>
<h:form>
<p><h:inputText value="#{indexBean.message}" p:placeholder="Enter text"/></p>
<p><h:outputText value="#{indexBean.message}" p:placeholder="Enter text"/></p>
</h:form>
</h:body>
</html>
実行
gradle tomcatRun
すると、
*******************************************************************
*** WARNING: Apache MyFaces-2 is running in DEVELOPMENT mode. ***
*** ^^^^^^^^^^^ ***
*** Do NOT deploy to your live server(s) without changing this. ***
*** See Application#getProjectStage() for more information. ***
*******************************************************************
Started Tomcat Server
The Server is running at http://localhost:8080/{projectName}
> Building 75% > :tomcatRun
で停止します。
この時点で、Tomcatが8080ポートで起動しているため、http://localhost:8080/{projectName}/hello
にブラウザーでアクセスすると、ブラウザー上には何も表示されませんが、
*******************************************************************
*** WARNING: Apache MyFaces-2 is running in DEVELOPMENT mode. ***
*** ^^^^^^^^^^^ ***
*** Do NOT deploy to your live server(s) without changing this. ***
*** See Application#getProjectStage() for more information. ***
*******************************************************************
Started Tomcat Server
The Server is running at http://localhost:8080/{projectName}
HelloServlet.doGet()
> Building 75% > :tomcatRun
と出力されます。
また、http://localhost:8080/{projectName}/index.xhtml
にブラウザーでアクセスすると、index.xhtmlが表示されるため、テキストボックスに適当に入力してEnterキーを押すと、入力した内容がテキストボックスの下に出力されます。
Tomcatの終了
Ctrl+Cで終わらせてあげてください(他に方法があるのかもしれませんが…)
あとがき
Servlet 3.1とJSF2.2とか、組み合わせが微妙っぽいですね。
JSF2.2(というか、JSFを使う場合全般?)は、Servlet 2.5とか、旧いバージョンのほうが、web.xmlなどがすっきり書けるようです。
しかし、myfaces以外のJSFの実装が、Tomcat8とServlet API3.1では動かないとは…
Jettyなら動きそうなのに。
やっぱり、Tomcatは時代遅れなのかな?(普通に仕事とかだとJetty使ってるし)