kagamihogeの日記

kagamihogeの日記です。

Java EE 8のMVC 1.0 + Faceletsのサンプルを試す

itblog.inginea.eu

Java EE 8導入予定のMVC 1.0を動かしてみたかったのでやってみる。それと、MVC 1.0 in Java EE 8: Getting started using facelets | .Lost in CodingというエントリでviewにはJSPの代わりにFaceletsも使えるよ、という話なので、このエントリの内容を試してみる。

環境

やること

プロジェクトを作る

MVC 1.0(Java EE 8)をとりあえず動かしてみた - Java EE 事始め!や、GlassFish 4さわる - kagamihogeの日記とかを参考にプロジェクトを作る。

GlassFish Toolsのインストール

このセクションはMVC 1.0の本筋とは無関係なので、関心が無ければ読み飛ばし推奨。

EclipseからGlassFishを起動するためにGlassFish Toolsをインストールする。GlassFish Toolsのページによると、Supports GlassFish 4.0 and 3.1とあり4.1.xは未サポートのように見える。が、Reviewsで動かないと嘆いている人が居る一方、 GlassFish 4.1 is definitely supported.とレスが返されている。それで、自分の環境では動作したので特に問題無し。

mavendependencyに参照実装のozarkを追加

Java EE 7のアプリケーションサーバには当然のことながらJava EE 8導入予定のMVC 1.0の依存性は含まれていない。そのため、Java EE 8がリリースされるまでは、mavenの依存性にそれを追加する必要がある。

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle.ozark</groupId>
            <artifactId>ozark</artifactId>
            <version>1.0.0-m01</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

Controller

package kagamihoge.glassfish.javaee8.mvcwithfacelets.controller;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.mvc.Controller;
import javax.mvc.Models;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("hello")
@Controller
@RequestScoped
public class HelloController {
    @Inject
    private Models model;
    
    @GET
    public String doGet() {
        System.out.println("hge");
        model.put("hello", "Hello MVC 1.0");
        
        return "hello.xhtml";
    }
}

Second, unless you include beans.xml with bean discovery mode all, you need to mark your controller with a scope-defining annotation, like @RequestScoped, to turn on CDI injection of Models model.

MVC 1.0 in Java EE 8: Getting started using facelets | .Lost in Coding より抜粋

「beans.xmlにbean discovery modeallを含めない限り、ModelsのCDIインジェクトを実行するためには、controllerにはスコープ定義アノテーションの@RequestScopedなどが必要」とのこと。

参考URL:GlassFish 4.0のCDIに潜む罠 - Programming Studio

JAX-RS application configuration

上記コントローラの実態はJAX-RSリソースなので設定用のクラスが必要。

package kagamihoge.glassfish.javaee8.mvcwithfacelets;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("api")
public class MyApplication extends Application {

}

View

Faceletsの設定をweb.xmlに追加する。

<?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"
    version="3.1">
    <display-name>mvcwithfacelets</display-name>
    <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>
</web-app>

src\main\webapp\WEB-INF\views\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="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h1>#{hello}</h1>
    </h:body>
</html>

http://localhost:8080/mvcwithfacelets/api/hello にアクセスして表示されればおk

f:id:kagamihoge:20160128185548j:plain

プロジェクト構成

f:id:kagamihoge:20160128185950j:plain

ハマったところ

重大: PWC6117: File "null" not found

viewの*.xhtmlなどはWEB-INF/views配下に置く必要がある。

参考URL

2016/01/29 追記

上記ツイートにあるようにGlassFish v5 (Java EE 8 RI) のnightly buildを http://download.java.net/glassfish/5.0/nightly/ から取得できるんで、こっち使っても良かったかもしれない。