Groovy で JSF を使ってみる

今更 JSF ? とか思われそうですが、サンプル or 簡易的な Web ページを作りたいけど少しでもリッチな UI にしたいという時に使えるんじゃないかと思って試してみました。

PrimeFaces

JSF の実装は PrimeFaces を使用します。

Jetty 上で PrimeFaces を使うチュートリアルが公開されているため、こちらを参考にしていきます。

codenotfound.com

Groovy プロジェクトを作成

今回も Gradle の type オプションで手っ取り早く雛形を作成してしまいます。

( 一番シンプルな構成なライブラリプロジェクトを作成します )

mkdir groovyJSF
cd groovyJSF
gradle init --type groovy-library

Web アプリケーションの設定

build.gradle に war プラグインと gratty プラグインを追加します。

build.gradle

plugins {
    id 'groovy'
    id 'war' // 追加
}
apply from: 'https://raw.github.com/akhikhl/gretty/master/pluginScripts/gretty.plugin' // 追加

dependencies {
    //compile 'org.codehaus.groovy:groovy-all:2.4.14'
    compile 'org.codehaus.groovy:groovy:2.5.6' // ついでに最新のバージョンにしておく

   〜
}

gretty {  // 追加
    servletContainer = 'jetty9.4'
    contextPath = '/'
}

gratty プラグインは Jetty や Tomcat を起動、アプリのデプロイ、さらにはホットリロードにも対応しているため、エディタ + JVM で Web アプリを作成するのにとても便利なプラグインです。

github.com

Groovy は groovy-all から groovy に変更します。これは Java と Jetty のバージョンの兼ね合いでサーバの起動に失敗してしまうみたいです。今回は簡単な表示確認までしか行わないので動作確認できたこの設定で一旦よしとします。

github.com

JSF の設定

build.gradle に PrimeFaces と必要なAPI を追加します。

build.gradle

dependencies {
    〜
    compile group: 'org.primefaces', name: 'primefaces', version: '7.0'
    compile group: 'com.sun.faces', name: 'jsf-api', version: '2.2.18'
    compile group: 'com.sun.faces', name: 'jsf-impl', version: '2.2.18'
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    〜
}

チュートリアルに従い、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">

  <!-- File(s) appended to a request for a URL that is not mapped to a web component -->
  <welcome-file-list>
    <welcome-file>helloworld.xhtml</welcome-file>
  </welcome-file-list>

  <!-- Define the JSF servlet (manages the request processing life cycle for JavaServer Faces) -->
  <servlet>
    <servlet-name>faces-servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- Map following files to the JSF servlet -->
  <servlet-mapping>
    <servlet-name>faces-servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
</web-app>

ページの追加

XHTML と Bean を追加します。

PrimeFaces のチュートリアルJava のコードなので Groovy に置き換えます。

src/main/groovy/HelloWorld.groovy

@javax.faces.bean.ManagedBean
public class HelloWorld {

  def firstName = "John"
  def lastName = "Doe"

  def showGreeting() {
    return "Hello ${firstName} ${lastName}!";
  }
}

Groovy だとかなりシンプルになりますね。

XHTML はそのままコピペ

src/main/webapp/helloworld.xhtml

<?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 xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui">

<h:head>
  <title>PrimeFaces Hello World Example</title>
</h:head>

<h:body>
  <h:form>

    <p:panel header="PrimeFaces Hello World Example">
      <h:panelGrid columns="2" cellpadding="4">
        <h:outputText value="First Name: " />
        <p:inputText value="#{helloWorld.firstName}" />

        <h:outputText value="Last Name: " />
        <p:inputText value="#{helloWorld.lastName}" />

        <p:commandButton value="Submit" update="greeting"
          oncomplete="PF('greetingDialog').show()" />
      </h:panelGrid>
    </p:panel>

    <p:dialog header="Greeting" widgetVar="greetingDialog"
      modal="true" resizable="false">
      <h:panelGrid id="greeting" columns="1" cellpadding="4">
        <h:outputText value="#{helloWorld.showGreeting()}" />
      </h:panelGrid>
    </p:dialog>

  </h:form>
</h:body>
</html>

実行確認

gretty プラグインを使いアプリを起動します。ホットリロードも対応しているので、build.gradle を変更した場合は再起動が必要ですが、それ以外のコードであれば少し待てば再読込が行われます。

$ gradle appRun

localhost:8080 にアクセスすると確認できました。以前は重量級のアプリケーションサーバでないと使えないイメージがあったのですが、かなり簡単に使えました。

f:id:erudoru:20190321175259p:plain

github.com