JSF2.2入門 第2回ユーザー入力

kanban2

katatsumuriユーザーからの入力を受け付ける

ここではユーザーから名前と生年月日を入力してもらい、その結果を表示するアプリケーションを作ります。

leaf入力のしくみ

入力方法はHTMLのフォームと同じで、送信ボタンを押すとサーバーに送られます。サーバーにはマネージドビーンという送信データを受けとる簡単なJavaのクラス(POJO:Plain Old Java Object)を用意しておきます。JSFの仕組みによって送信された情報はマネージドビーンのプロパティに自動的にセットされます。そのあとは、JSFページでこれらプロパティを読み取り表示します。

JSFを使わない場合、サーブレットを作って送信されたデータを受け取りますが、その部分ががとても簡単になるというわけです。

leafマネージドビーンをつくる

マネージドビーンはJavaビーンズのようなものですが、要するにシンプルなJavaクラスです。マネージドビーンはJSFの仕組みによってインスタンス化やメソッドの呼び出しが自動的に行われるため「マネージド」(管理されている)という名前がついているのです。

作り方について説明します。

すべてのJavaクラスはパッケージの中に入れるべきです。NetBeansのプロジェクトウインドウでMyFirstプロジェクトの中のソースパッケージのところで右クリックして「新規パッケージ」を実行して続くウィザードでパッケージ名を設定します。ここでは「com.myjsf」としましょう。

21package-b

22package2

次にcom.myjsfパッケージのところで右クリックして[新規]-[JSF管理対象ビーン]を実行します。

23bean1

まずマネージドビーンの名前を決めます。Javaクラスなので最初は大文字で、UserInfoBeanとしましょうか。スコープの指定がありますがセッションを選びます。次のひな形のコードが自動的に作られます。これを編集してあなたのビーンを作るのです。

package com.myjsf;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
@Named(value = “userInfoBean”)
@SessionScoped
public class UserInfoBean implements Serializable {
public UserInfoBean() {
}
}

この中で@NamedはJNDI(Java Naming and Directory Interface)とよばれるJavaのネームサービスをもとにできているものです。JNDIはオブジェクトを名前で区別して検索したり教えてくれる機能です。

Namedアノーテーションは、このビーンズを参照するときの名前でクラス名の先頭が小文字になったものをデフォルトとしてセットしてくれます。別の名前に変えても構いません。SessionScopedアノーテーションはこのビーンズの生存期間がセッションであるということ。

次にユーザーから受けとりたい情報と形式を決めましょう。これはビーンの中でプロパティを用意するということです。名前を受け取りたいのでuserNameというプロパティを用意することにします。形式はString型がよいですね。

生年月日はbirthDayとします。これは1995/10/2とか1995.10.02とか色々な入力が想定されます。とりあえずどれにも対応できようString型にしておきます。後でよい方法を教えます。

・・・
public class UserInfoBean implements Serializable {
String userName;
String birthDay;
public UserInfoBean() {
・・・

マネージドビーンの規則として原則としてプロパティに値をセットするためのメソッド、セッターといいますがそれを用意しなければなりません。同じく値を読み出すためのメソッド、ゲッターを用意しなければなりません。それらの名前の付け方が決まっていて、userNameプロパティ用ならばsetUserName()、getUserName()とします。プロパティ名の先頭を大文字にしてその前にsetやgetを付けます。これは絶対まもらなければならないルールです。JSFのシステムはプロパティ名だけが分かれば、そのアクセスメソッド名は必ずわかるという仕組みになっています。

セッターとゲッターは私たちがコツコツと打ち込んで作ることもできるのですが、そんな単純な作業はお任せくださいとも言うようにNetBeansでは便利な方法が用意されています。

コードの中でセッターとゲッターを挿入したい場所にカーソルを置いて右クリックしてコンテキストメニューから「コード挿入」を選びます。次に「取得メソッドおよび設定メソッド」を選ぶと、どのプロパティに対してメソッドを作るか聞かれるので全部を選びます。最上位のチェックマークを選ぶとすべてのものが選ばれます。

24ins-code1

25ins-code2

これが完了するとコードが自動的に挿入されます。

26ins-code3

完成したマネージドビーンのコードは次のとおり完璧です。NetBeansを使うと生産性は格段に向上します。

package com.myjsf;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@Named(value = “userInfoBean”)
@SessionScoped
public class UserInfoBean implements Serializable {

String userName;
String birthDay;

public UserInfoBean() {
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getBirthDay() {
return birthDay;
}
public void setBirthDay(String birthDay) {
this.birthDay = birthDay;
}

JSFのマネージドビーンは、これまでJavaEE6以前では@ManagedBeanというアノーテーションを使っていましたが、今後は@Namedを使っていくようになります。最新のNetBeansでは「@ManagedBeanは推奨されません」と表示されます。現在はコンパティビリティのために正常に動作しますが将来は使用できなくなる可能性があります。次の2つのビーンのコードを見てください。ゴシックのところが違います。

[従来のマネージドビーンの記述]・・・今後推奨されない

package com.myjsf;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class UserInfoBean implements Serializable{

・・・・

[これからのマネージドビーンの記述]・・・推奨

package com.myjsf;
import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named(value = “userInfoBean”)
@SessionScoped
public class UserInfoBean implements Serializable {

 

後者のコードはCDI(Contexts and Dependency Injection)タイプのマネージドビーンと呼ばれていています。CDIは Java EE 6から追加された(Dependency Injection、依存性注入)のための仕様で、Java EE 7におけるCDIのバージョンは1.1で、Java EE 7から CDIはデフォルトで有効化されています。今後はこのCDIを使った方式を推奨していくようですので、上記の後者のコードを使っていくとよいと思います。

leafJSFページをつくる

JSFページはユーザーからの入力を受け付けてマネージドビーンに格納することが簡単にできます。NetBeansで[新規ファイル]でregisterという名前のJSFページを作ります。

HTMLと同様にh:formタグを使います。そのなかにh:inputTextタグを書きます。これはHTMLのinput type=”text”と同じ意味です。

h:inputTextのvalue属性の書き方がJSFの最大のメリットです。マネージドビーン名とプロパティ名をドットで結んでかっこでくくって#をつけます。このときマネージドビーン名は”デフォルト”ではマネージドビーンのクラス名の先頭1文字を小文字にしたものにします。

value=”#{マネージドビーン名.プロパティ名}”

このようにするだけでユーザーがフォームを送信すると、JSFによってその値が自動的にマネージドビーンのプロパティにセットされるのです。プログラマーは入力機能の部分を書かなくてもよいのです。

NetBeansでは次の画面のようにマネージドビーン名を入力してピリオドを打つと、そこに登録されているプロパティを自動的に表示してくれますので選ぶだけで間違いもなく早くコードが書けます。h:inputタグのidは空のままなので何か記入します。

27code-auto-ins

送信ボタンはh:commandButtonで作ります。このままだとサーバーに送信した名前と生年月日が本当に届いているか確認できませんからh:outputTextタグを使って送信した値をページ内に表示しましょう。valueプロパティはh:inputTextタグと同様です。f:viewというタグがありますが、これはJSF関係のタグを含めるための入れもの的なものです。最終的には次のようなコードになります。

<?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”
xmlns:f=”http://xmlns.jcp.org/jsf/core”>
<f:view>
<h:head>
<title>User Registration</title>
</h:head>
<h:body>
<h:form>
お名前<h:inputText value=”#{userInfoBean.userName}”/><p/>
生年月日<h:inputText value=”#{userInfoBean.birthDay}”/><p/>
<h:commandButton type=”submit” value=”送信” />
<h:commandButton type=”reset” value=”キャンセル” /><p/>
</h:form>
<h:outputText value=”#{userInfoBean.userName}”/><p/>
<h:outputText value=”#{userInfoBean.birthDay}”/>
</h:body>
</f:view>
</html>

leaf実行する

プロジェクトウィンドウのregister.xhtmlファイルで右クリックして[ファイルの実行] を選びます。

28runブラウザーが自動的に立ち上がって入力ページが表示されますので、何か適当に入れます。

28run2

送信ボタンを押します。送信とキャンセルボタンの下に入力した情報がそのまま表示されることになっていますが、漢字が変なふうに化けてしまいました。

29error

ブラウザーの戻るボタンを押して、入力欄に正常な漢字になっていることを確認したうえでもう一度送信ボタンを押します。今度は正常に表示されました。

28run3

これは調べてみるとJSF2.xのバグの模様でリクエストのパラメータのエンコーディングが最初はうまく機能せず文字化けして2回目以降はずっと正常になるという現象です。

leaf文字化け対策

今後のバージョンアップでは改善すると思いますが、ネット上の情報では対策としてglassfish-web.xmlあるいはsun-web.xmlに次のように文字コードのエンコーディング指定をすればよいとのアドバイスありますがうまくいかないようです。

<parameter-encoding default-charset=”UTF-8″ />

ここでは確実な方法としてフィルターを利用します。

30filter1

ソースパッケージにEncodingFilter.javaを作ります。そして次のようなコードを書きます。これはweb.xmlに書いた「encoding」パラメータを読み取ってリクエストに対してsetCharacterEncodingメソッドでエンコーディング設定を行うフィルターです。

package com.myjsf;
import java.io.*;
import javax.servlet.*;

public class EncodingFilter implements Filter {
private String encoding;

@Override
public void init(FilterConfig config) throws ServletException {
encoding = config.getInitParameter(“encoding”);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
@Override
public void destroy() {}
}

NetBeansのプロジェクトウインドウでWEB-INFの下にあるweb.xmlをダブルクリックで開いて次の太字の部分を追記します。servlet-mappingタグが終わったあたりがいいと思います。

30filter2

・・・・

</servlet-mapping>
<filter>
<filter-name>Encoding</filter-name>
<filter-class>com.myjsf.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

・・・・

このweb.xmlの設定はurl-patternタグですべてのurlに対してEncodingという名前のフィルターを必ず通すように指定しています。Encodingはfilter-nameタグで定義されていて、さっき作ったcom.myjsf.EncodingFilterであることが明示されています。これが実行されるのです。param-nameタグでencodingはutf-8とセットされていますから、必ずエンコーディングはUTF-8になります。

leafふたたび実行

実行すると次のようにページが表示されます。

31rerun1

何か入力して送信ボタンを押します。

31rerun2

今度は最初から文字化けせずに正常に表示されました。

31rerun3

leafまとめ

  • ユーザー入力はJSFのh:inputTextタグなどで受け付ける
  • 入力情報の出力はJSFのh:outputTextタグなどを使う
  • ユーザー入力情報はJSFによってマネージドビーンのプロパティに自動的にセットされる
  • マネージドビーンはJSFが自動的に管理してくれるのでインスタンス化などプログラマが行う必要はない。任せる。

バグがあったりして、ちょっと長くなってしましたが、今回はここまでです。

previousnext

JSF2.2のすべてをまとめたkindle電子書籍 「JavaServer Faces2.2 入門」もぜひご覧ください。パソコン、iPhone、Androidどんな端末用にもamazonが無料のKindle電子書籍リーダーを用意しています。それをつかってKindle本を手軽にお楽しみください。あなたが今お使いの端末用Kidle電子書籍リーダーのご案内

同書籍のPDF版は私自身が運営するこちらのサイトから直接購入できます。

JSF2.2入門 第1回JSFとは何か

kanban1
katatsumuriJSFとは何か

leafJSFとは

JSFはJavaServer Facesの略で、JavaベースのWebアプリケーションフレームワークです。Javaの企業向けなど大規模システムに利用されるJava Platform, Enterprise Edition (Java EE) の仕様のひとつになっています。ベースになっている技術はJavaサーブレットです。

 

JSFは2004年にSun Microsystemsが開発したものですが、現在ではSunを買収したOracleが引き継いで推進しています。Facesという言葉からもわかるようにWebアプリケーションにおいてユーザーから見た”顔”、つまり使いやすくてデザインのよいユーザーインターフェースを簡単に作ることを主眼においたフレームワークです。

主なメリットはつぎのとおりです。

  • HTMLタグと同様のタグが多数用意されている。
  • タグを使って簡単にフォーム入力欄が作れる(UIコンポーネント)
  • 入力値が適正な範囲かどうかなどチェックが簡単にできる(バリデーション機能)
  • 入力値の型変換が簡単にできる(コンバータ機能)
  • 入力値をプログラミング無しにJavaBeansに格納できる(バインディング機能)
  • ページ移動を簡単に設定できる(ナビゲーション機能)

これらはどのフレームワークでも実現できますが少々プログラミングが必要でした。JSFはそのプログラミングをなるべく少なくして効率よく開発できるようになっています。

ここで解説するJSFのバージョンは最新の2.2(2013年5月リリース)です。

leafJSFのための開発環境

JSFを使ったWebアプリケーションを開発するためには次の環境が必要です。リンクをクリックすればサイトに飛びます。

  • Java SE(Javaのコンパイラーと実行環境)
  • NetBeans IDE(ソフト開発ツール、Webサーバー・サーブレットコンテナ)

なおNetBeansのパッケージは色々な種類がありますがJavaEEに対応したものをダウンロードします。このパッケージにはJSFを実行するためのサーバーであるGlassFishとTomcatが入っていて選べるようになっています。

02NB

NetBeansすべての必要なものがワンパッケージになっていますから環境構築でうまくいかなくて苦労するケースが極めて少ないと思います。Eclipseも昔よりはだいぶ楽になりましたが、EcliseやNetBeansをまったく使ったことがない人には私はNetBeansをお勧めします。NetBeansは特に難しい設定はなく、インストールのウィザードに従って進んでいけばOKです。それとJavaを推進しているお家元のOracleがサポートしているものだからです。

leafはじめてのJSF

NetBeansを起動すると次のような画面が出ます。

03newproject

(1)プロジェクトの種類選択

新規プロジェクトを作成します。プロジェクトとは複数のJSFページやそのほかのプログラムから構成されているものです。新規作成するにはNetBeansの[ファイル]-[新規プロジェクト]を実行します。

次のようにどの種類のプロジェクトを作るか聞かれますので「Java Web」「Webアプリケーション」を選びます。

04category

(2)名前と保存場所

次にプロジェクト名プロジェクトの保存場所が聞かれます。ここではプロジェクト名として「MyFirst」を入力しました。プロジェクトの場所などは自動的に決めてくれますので確認だけすればよいでしょう。

05projectname

(3)フレームワークの設定

JSFを使ったプロジェクトにするので、JavaServer Facesにチェックを入れます。下の欄にはJSF2.2のライブラリを使用すると自動的に表示されます。なお、フレームワークを選んでいないプロジェクトでもJSFを使うこともできます。

07framework

(4)完成

以上でNetBeansの画面には、左側「プロジェクト・ウィンドウ」に作成した「MyFirst」プロジェクトとその中に自動的に作成されたディレクトリやファイルが表示されます。右側「ファイル・ウィンドウ」にはindex.xhtmlファイルが編集できるように表示されています。

08firstshot

自動的に作られたindex.xhtmlは次のようになっています。単純に「Hello from Facelets」という文字が表示されるだけの機能ですがJSFで作られています。
<?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>
Hello from Facelets
</h:body>
</html>

このファイルの拡張子はxhtmlです。JSFのタグを使ったページはこのファイル形式です。以前のJSFバージョン1ではJSP(JavaServer Pages)が使われていましたがバージョン2.0以降はこの形式です。これをFaceletsと呼びます。FaceletsはJSFのタグを使うための方式(技術)を意味しています。このファイルはJSFページと呼んでも結構です。

htmlタグの中にh=”http://xmlns…..と書いてありますがh:bodyタグなどhが付くタグを使うときにはこの宣言が必要です。NetBeansではこのタグを使うと自動的にこの宣言をhtmlタグに含めてくれます。

(5)実行

JSFを実行するには、実行するFaceletsのファイルを選択して右クリックして「実行」です。

09run

なお、NetBeansの画面の上のほうに緑の三角で「実行」アイコンがありますが、これは現在選択されている「プロジェクト」を実行するものです。ここで新規作成したMyFirstプロジェクトを実行するという意味で、通常はプロジェクトの中のindex.xhtmlなどプロジェクトの入り口の代表ファイルを実行します。したがって例えばsample1.xhtmlなどといったJSFページを実行しようと思うと、このアイコンではできません。右クリックで実行してください。

あなたのPCのデフォルトのブラウザーが自動的に立ち上がって結果を表示してくれます。なんでもない結果ですが、これがあなたの作った最初のJSFです。アドレス欄にはlocalhostから始まる文字列が書いてありますが、これはあなたのPC内部のGlassFishサーバーが起動して、そのうえで実行されたものです。

10result

leafちょっと改造

さきほどはNetBeansが自動的に作ってくれたFaceletsを実行しただけで、あなたはほとんど何もしていません。もうひとつ、あなた独自のものを作ってみましょう。日本語を交えて。

NetBeansのプロジェクトウィンドウでMyFirstプロジェクトを選んで、[ファイル]-[新規ファイル]を実行します。次のようにファイルの種類を聞かれますので「JavaServer Faces」で「JSFページ」を選びます。

11newpage1

次にファイル名を聞かれますので「helloJP」としてみます。なお、ファイル名はNetBeansのプロジェクトウインドウでファイル名のところを直接編集して変更することが可能です。

12newpage2

JSFページが作られます。titleとbodyの中の文字を日本語に変えてみましょう。

13newpage3

<?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>JSFページ</title>
</h:head>
<h:body>
はじめてのJSF
</h:body>
</html>

実行すると次のようになります。

14result

だいぶ長くなったので、はじめてのJSFはここまでにしょうましょう。

next

JSF2.2のすべてをまとめたkindle電子書籍 「JavaServer Faces2.2 入門」もぜひご覧ください。パソコン、iPhone、Androidどんな端末用にもamazonが無料のKindle電子書籍リーダーを用意しています。それをつかってKindle本を手軽にお楽しみください。あなたが今お使いの端末用Kidle電子書籍リーダーのご案内

同書籍のPDF版は私自身が運営するこちらのサイトから直接購入できます。