2024年JSF(Jakarta Faces)をTomcatで試すメモ

JSF(Jakarta Faces)をTomcatで試すメモ
Jakarta Faces」って長いので、ここではJSFって書きます。

Tomcat用のプロジェクトがあるとして追加する、って感じで書くので、基本的な構成は省略。
Tomcat 10.1.24で試してます。
https://tomcat.apache.org/download-10.cgi

最初から構成を作るのであれば、Quarkusが無難かなぁという気はする。
その場合はstarterでPrimeFacesを選ぼう。
https://code.quarkus.io/

Jakarta EEがよければ、Eclipse Starter for Jakarta EEで。そうするとPlatform ProfileかWeb ProfileであればJSFは含まれるので設定不要のはず
https://start.jakarta.ee/

Springとは相性がわるいです、たぶん。

設定

ということでTomcatに組み込む設定

mojarra組み込み

今回はJSFの実装にはmojarraを使います。
導入方法はREADME.mdにだいたい書いてあります。
https://github.com/eclipse-ee4j/mojarra/blob/4.0/README.md

Bean Validator使いたかったら最新バージョンを指定しろと書いてあるので、もし使いたければここで調べましょう。8.0.1が最新かな。
https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator

けど、必要なものだけであれば次のふたつをdependencyに追加すればよさそう。CDIに依存するようになったので、weldも組み込みます。

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.faces</artifactId>
    <version>4.0.7</version>
</dependency>
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-shaded</artifactId>
    <version>4.0.0.Final</version>
</dependency>

mojarraではなくMyFacesを使ってもいいと思う。Quarkusだとこちらになるはず。
https://myfaces.apache.org/

web.xmlの設定

web.xmlにFacesServletの設定が必要になります。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="6.0" xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd">
    <context-param>
        <param-name>jakarta.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
        <!-- <param-value>Production</param-value> -->
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>jakarta.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.html</welcome-file>
    </welcome-file-list>
</web-app>

beans.xml

CDIを有効にするためにbeans.xmlが必要です。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
       bean-discovery-mode="all">
</beans>

試しに動かす

じゃあ動かしてみましょう。

faceletを書く

画面をfaceletとして書きます。
hello.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="jakarta.faces.html"
      xmlns:f="jakarta.faces.core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h1>Hello JSF</h1>
        <f:view>
        <h:form>
            <div>
                <h:inputText id="in" value="#{helloBean.input}"/>
                <h:commandButton value="Hello" actionListener="#{helloBean.go()}">
                    <f:ajax execute="in" render="out"/>
                </h:commandButton>
            </div>
            <h:outputLabel id="out" value="#{helloBean.message}"/>
        </h:form>
        </f:view>
    </h:body>
</html>

管理ビーンを作る

処理をするための管理ビーンを書きます。

package example;

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

@Named
@RequestScoped
public class HelloBean {
    private String message = "Hello!!!";
    private String input = "";

    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getInput() {
        return input;
    }
    public void setInput(String input) {
        this.input = input;
    }
    
    public void go() {
        message = "hello " + input;
    }
}

実行

うごいた