JSF2.2入門 第11回ELでArrayListとHashMap


kanban11

katatsumuriマネージドビーンのArrayListとHashMapにアクセス

前回は配列までのアクセス方法について説明しましたが、今回はArrayListとHashMapについてです。ArrayListはサイズが可変の配列でadd()メソッドでどんどん要素追加できます。HashMapはmap.put(キー,値)という方法で要素追加しmap.get(キー)で要素を参照できます。

leafマネージドビーン

マネージドビーンにArrayListとHashMapを使った例は次のとおりです。コンストラクタで値はセットしています。それらのゲッターとセッターは普通に用意します。

public class BookBean implements Serializable{
String title;
String auther;
Detail bookdetail;
String[] bungakuShubetsu=new String[2];
ArrayList<String> toujoujinbutsu=new ArrayList();
HashMap<String,String> map=new HashMap();

public BookBean() {
title=”吾輩は猫である”;
auther=”夏目漱石”;
bookdetail=new Detail(“1905-10-06″,500,”服部書店”);
bungakuShubetsu[0]=”日本文学”;bungakuShubetsu[1]=”小説”;
toujoujinbutsu.add(“吾輩”);toujoujinbutsu.add(“車屋の黒”);toujoujinbutsu.add(“三毛子”);toujoujinbutsu.add(“苦沙弥先生”);
map.put(“吾輩”,”猫”);map.put(“車屋の黒”,”猫”);map.put(“三毛子”,”猫”);map.put(“苦沙弥先生”,”人間”);
}
・・・
public HashMap<String, String> getMap() {
return map;
}

public void setMap(HashMap<String, String> map) {
this.map = map;
}

public ArrayList<String> getToujoujinbutsu() {
return toujoujinbutsu;
}

public void setToujoujinbutsu(ArrayList<String> toujoujinbutsu) {
this.toujoujinbutsu = toujoujinbutsu;
}
・・・
}

leafJSFページ/ArrayList

ArrayListへのアクセス方法について説明します。

1.個々の要素の参照

配列と同様にインデックスを指定してアクセスできます。

<h:outputText value=”#{bookBean.toujoujinbutsu[0]}”/>
<h:outputText value=”#{bookBean.toujoujinbutsu[1]}”/>
<h:outputText value=”#{bookBean.toujoujinbutsu[2]}”/>
<h:outputText value=”#{bookBean.toujoujinbutsu[3]}”/>

el5arraylist

2.c:forEach

配列と同じ方法で適用できます。表示は前の例と同じ。

<c:forEach var=”item” items=”#{bookBean.toujoujinbutsu}”>
#{item}
</c:forEach>

3.ui:repeat

これも配列のときと同じです。panelGridを使った場合でも1要素として1セルに入ります。

<ui:repeat var=”item” value=”#{bookBean.toujoujinbutsu}”>
#{item},
</ui:repeat>

el6arraylist2

なおこれらのcやuiタグを使うにはJSFページのxhtmlで次のようしておく必要があります。

<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:h=”http://xmlns.jcp.org/jsf/html”
xmlns:c=”http://xmlns.jcp.org/jsp/jstl/core”
xmlns:ui=”http://xmlns.jcp.org/jsf/facelets”>

leafJSFページ/HashMap

HashMapへのアクセスについて説明します。

HashMapのキーを指定します。カッコとシングルクォーテーションを使います。ごく自然ですね。

<h:outputText value=”#{bookBean.map[‘吾輩’]}”/>
<h:outputText value=”#{bookBean.map[‘苦沙弥先生’]}”/>

el5hashmap

次のようにピリオドを使ったアクセスは、漢字を使っているので難しいかなと思いましたが、実は問題なく実行できます。

<h:outputText value=”#{bookBean.map.吾輩}”/>
<h:outputText value=”#{bookBean.map.苦沙弥先生}”/>

 

previousnext

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

JSF2.2入門 第10回ELの基本


kanban10

katatsumuriEL(Expression Language)

はJSFやJSPにおいて、つまりはJavaEEの世界において、プレゼンテーションレイヤーからマネージドビーンというアプリケーションのロジックレイヤーに簡単にアクセスできるようにする重要なコミュニケーション機能です。ここでは基本的な使い方について説明します。

leafマネージドビーンのプロパティへのアクセス

これまでのサンプルでも使ってきたように、ユーザー入力をマネージドビーンの特定のプロパティに送信して設定するにはh:inputTextタグのvalueプロパティに#{ビーン名.プロパティ名}というEL式を指定します。

<h:inputText value=”#{userBean2.userName}”/>

同様にh:outputTextで同じEL式を使うと、マネージドビーンのプロパティの現在の値が表示できます。

つまり次の図のようにEL式によってマネージドビーンとの間で設定と読み出しが簡単にできるというわけです。具体的にはマネージドビーンのメソッドがコールされます。

EL1

leafマネージドビーンの内部クラスのプロパティにアクセス

2つ目の例として、マネージドビーンのプロパティにアクセスするというところまでは同じですが、そのプロパティがオブジェクトであった場合にどうなるでしょうか。Stringもオブジェクトですが、それとは別に。

次の図にあるBookBeanは1冊の本の情報を保持するものです。title(題名)、auther(著者)まではStringです。Detailオブジェクトとしてbookdetailを持っています。これはpubdate(出版日)、pages(ページ数)、publisher(出版社)などさらに詳細情報を意味します。

次のh:outputTextは詳細情報の中のpubdateを表示するものです。つまりマネージドビーンの中の子供クラスの中のプロパティを読み出しています。このような場合には#{bookBean.bookdetail.pubdate}と入れ子状に表現すればよいのです。EL2

もちろんJavaのクラスとしてはこのDetailクラスはマネージドビーンの中で定義されている必要はありません。アクセスできるようになっていれば外でも構いません。

アクセス方法は単純にピリオドで接続する方法のほかにカッコとシングルクォーテーションを使った方法のどちらも可能です。それらのミックスでも構いません。

<h:outputText value=”#{bookBean.bookdetail.pubdate}”/>

<h:outputText value=”#{bookBean[‘bookdetail’][‘pubdate’]}”/>

シングルクオーテーションとダブルクォーテーションは次のどちらかのパターンにします。”#{aaa[‘bbb’][‘ccc’]}”か’#{aaa[“bbb”][“ccc”]}’、前者のほうが自然でしょうね。

leafここまでのまとめ

次のようなJSFページにすると

<h:panelGrid columns=”2″ styleClass=”grid”>
タイトル<h:outputText value=”#{bookBean.title}”/>
著者<h:outputText value=”#{bookBean.auther}”/>
ページ数<h:outputText value=”#{bookBean.bookdetail.pages}”/>
発行年<h:outputText value=”#{bookBean.bookdetail.pubdate}”/>
出版社<h:outputText value=”#{bookBean.bookdetail.publisher}”/>
</h:panelGrid>

こんなふうに表示されます。

el2output

マネージドビーンは次のようになっています。

[BookBean.java]

public class BookBean implements Serializable{
String title;
String auther;
Detail bookdetail;
public BookBean() {
title=”吾輩は猫である”;
auther=”夏目漱石”;
bookdetail=new Detail(“1905-10-06″,500,”服部書店”);
}
・・・
public class Detail{
String pubdate;
int pages;
String publisher;
public Detail(String pubdate,int pages,String publisher){
this.pubdate=pubdate;
this.pages=pages;
this.publisher=publisher;
}
・・・
}}

leafマネージドビーンの配列プロパティにアクセス

もしプロパティが配列の場合にどのようにアクセスするか説明しましょう。次のBookBeanではbungakuShubetsuが要素2つをもつ配列になっています。この例ではコンストラクタで設定してしまっています。

public class BookBean implements Serializable{
・・・
String[] bungakuShubetsu=new String[2];
・・・
public BookBean() {
・・・
bungakuShubetsu[0]=”日本文学”;bungakuShubetsu[1]=”小説”;
・・・
}
・・・
public String[] getBungakuShubetsu() {
return bungakuShubetsu;
}
・・・
}

JSFページから配列プロパティを参照するには、基本的には次のようにします。ごく自然に配列のインデックスを指定します。

<h:outputText value=”#{bookBean.bungakuShubetsu[0]}”/>
<h:outputText value=”#{bookBean.bungakuShubetsu[1]}”/>

leaf便利な配列へのアクセス

JSTLのcoreタグやuiタグを使うと繰り返し動作で簡単に配列を表示できます。

1.c:forEach その1

これはforループですね。アクセスする要素の開始と終了インデックスを指定することができます。なおこのコードはh:panelGridタグで挟んでいます。

<c:forEach begin=”0″ end=”1″ var=”i”>
要素#{i}は#{bookBean.bungakuShubetsu[i]}
</c:forEach>

el3array

2.c:forEach その2

インデックス指定なしでループするパターン。

<c:forEach var=”item” items=”#{bookBean.bungakuShubetsu}”>
#{item}
</c:forEach>

3.ui:repeat

ループの別パターン。

<ui:repeat var=”item” value=”#{bookBean.bungakuShubetsu}”>
#{item},
</ui:repeat>

これもh:panelGridタグでcolumns=”2″としていますが、前の2事例とは違って1つのセルに詰め込まれてしまいます。

el4array

なおこれらのcやuiタグを使うにはJSFページのxhtmlで次のようしておく必要があります。

<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:h=”http://xmlns.jcp.org/jsf/html”
xmlns:c=”http://xmlns.jcp.org/jsp/jstl/core”
xmlns:ui=”http://xmlns.jcp.org/jsf/facelets”>

 

previousnext

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

JSF2.2入門 第9回データテーブル


kanban9

katatsumuri表を作る

簡単にいうとテーブルです。JSFのh:dataTableというものを使いますが、これは結局はHTMLのtableタグに変換されます。しかしJSFのタグはテーブルにするデータを直接ページに書き込むことよりも、データベース等からダイナミックに取り出してデータ数も自由自在に表示できることが最大の強みです。

ここではデータベース利用も紹介します。

leafこんな表にしたい

外車の簡単なカタログを作ってみます。左の列から、写真、ブランド、モデル、カラー、価格、をテーブル表示します。

160606-8

leafデータベースを使う

NetBeansに組み込まれているJavaDBを使います。サービスウィンドウを開くとそれが見えます。右クリックして[データベースの作成]を実行します。

160606-1dbcreate

データベース名とユーザー名など聞かれます。データベース名はcarsとしました。パスワードはあとでコーディングのときに必要になるので忘れないように。

160606-2dbcreate2

データベースへのコネクションが作られます。右クリックで[接続]を実行します。

160606-3connection

接続されるとコネクションを展開することができて、表のところで[表を作成]を実行します。

160606-4table1

表、つまりデータベースのテーブル作成に入ります。表の名前とか、必要なカラムを作ります。BRAND、MODEL、COLOR、PRICEの4つを作ります。PRICEだけINTEGERでほかはVARCHARです。

160606-5table2

NetBeansのサービスウィンドウにIMPORTCARSという表ができます。そこで右クリックして[コマンドを実行]を実行すると、メイン・ウィンドウにSQL文が実行できる準備が整います。次のようにデータを登録するSQL文を打ち込みます。

160606-6insert

SQLの実行ボタンを押すとデータベースにデータが登録されます。エラーが出なければです。エラーが出るのは大体が誤字、脱字です。よく確かめましょう。そのウィンドウでSQLを修正して再度実行すればOKです。SQL文はこんな感じです。

INSERT INTO KAWASAKI.IMPORTCARS (BRAND,MODEL,COLOR,PRICE) VALUES(‘Mercedes’,’C180AVANTGARDE’,’RED’,486);

160606-10run

サービスウィンドウで表IMPORTCARSで右クリックして[データを表示]を実行するとデータが全部表示されます。メインウィンドウでつぎのSQL文実行してもOKです。

SELECT * FROM KAWASAKI.IMPORTCARS;


160606-7insertresult

これでデータができました。

leafマネージドビーン

このマネージドビーンはデータベースにある全部の車情報carsを返すものです。赤のところがポイントです。

carsはArrayListになっていて長さが可変です。search()メソッドでデータベースから検索してcarsに情報をセットします。あとはcarsを返すだけの機能です。ゲッターやセッターの掲載はだいぶ省いています。

あと紫色の部分を見てください。このクラス内にCarという1台分の車情報を保持するためのクラスを作ります。各プロパティにアクセスするためのゲッターとセッターを用意します。

データベースを使うにはまず青字の部分でデータベースcarsにコネクションを張ります。ここでデータベースを作成したときのユーザー名とパスワードが必要となります。

中心となる検索のためのserch()メソッドですが、まずStatementを取得し、SQL文で全部を検索する命令を用意します。それをstatementに渡して実行させます。結果はResultSetに入ってきますから、そこからBRAND、MODELなど各情報を取り出してArrayListのcarsに追加していくのです。

@Named(value=”carsBean”)
@RequestScoped
public class CarsBean {
ArrayList cars;
Connection connection;

public CarsBean() {
}

public ArrayList getCars() {
cars=new ArrayList();
open(); //DBコネクションのオープン
search(cars);//検索の実行、結果をcarsに取得
close();//DBコネクションのクローズ
return cars;
}

public void setCars(ArrayList cars) {
this.cars = cars;
}

//DBコネクションオープンのプライベートメソッド
private void open(){
try {
Class.forName(“org.apache.derby.jdbc.ClientDriver”);
//コネクション作成
connection=(Connection) DriverManager.getConnection(“jdbc:derby://localhost:1527/cars”,”kawasaki”,”kawasaki”);
}catch(ClassNotFoundException | SQLException e){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(“データベースオープンエラーです”));
}
}
//DBコネクションクローズのプライベートメソッド
private void close(){
try{
if(connection!=null) {
connection.close();
}
}catch(Exception e){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(“データベースCLOSEエラーです”));
}
}
//データベース検索
private ArrayList search(ArrayList data){
try{
//テーブルから全てのアイテムを取得する
try (Statement statement = (Statement) connection.createStatement()) {
//テーブルから全てのアイテムを取得する
String sql=”SELECT * FROM KAWASAKI.IMPORTCARS”;
try (ResultSet rs = statement.executeQuery(sql)) {
while(rs.next()) {
String brand=rs.getString(“BRAND”);
String model=rs.getString(“MODEL”);
String color=rs.getString(“COLOR”);
int price=rs.getInt(“PRICE”);
//商品名、価格でPcItemオブジェクト作成、dataへ追加
data.add(new Car(brand,model,color,price));
}
}
}
}catch(Exception e){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(“データベース検索エラーです”));
}
return data;
}

public class Car{
String brand;
String model;
String color;
int price;
public Car(String brand,String model,String color,int price){
this.brand=brand;
this.model=model;
this.color=color;
this.price=price;
}

public String getBrand() {
return brand;
}
・・・省略
}
}

ちょっと複雑だったでしょうか。

leafどう表にするか

h:dataTableタグを使います。valueにビーンのcarsを指定します。ここに全車のデータが入ってきます。そこから1台ずつのデータをvarプロパティで指定したcarに取り込み、そのあとでcarの中のbrandとかさまざまなプロパティにアクセスするのです。

テーブルの各列は色分けして表示しました。どれも同じ方法です。f:facet name=”header”は表の先頭行を作るものです。写真を表示しているのはh:graphicImage url=”/images/#{car.model}.jpg”という部分で、car.modelで入手した文字列に.jpgをつけた画像ファイルを表示しているだけです。そのほかブランド名のところでも#{car.brand}で値を取得して表示しています。車の台数はいくつあっても表のサイズは自動的に作られます。なおCSSでテーブルのスタイルを設定しています。
160606-8

<h:body>
<h2>IMPORT CARS</h2>
<h:dataTable border=”1″ var=”car” value=”#{carsBean.cars}” styleClass=”datatable”>
<h:column>
<f:facet name=”header”>
<h:outputText value=”PHOTO”/>
</f:facet>
<h:graphicImage url=”/images/#{car.model}.jpg”/>
</h:column>
<h:column>
<f:facet name=”header”>
<h:outputText value=”BRAND”/>
</f:facet>
<h:outputText id=”id1″ value=”#{car.brand}”/>
</h:column>
<h:column>
<f:facet name=”header”>
<h:outputText value=”MODEL”/>
</f:facet>
<h:outputText id=”id1″ value=”#{car.model}”/>
</h:column>
<h:column>
<f:facet name=”header”>
<h:outputText value=”COLOR”/>
</f:facet>
<h:outputText id=”id1″ value=”#{car.color}”/>
</h:column>
<h:column>
<f:facet name=”header”>
<h:outputText value=”PRICE”/>
</f:facet>
<h:outputText id=”id3″ value=”#{car.price}”/>
</h:column>
</h:dataTable>
</h:body>

leaf画像の置き場所

画像はJSFページからアクセスしやすいところにフォルダーを作って入れましょう。画像ファイル名はさっき言ったようにMODEL名と一致していることが、このプログラム設計上で必要です。

320iSE

C180AVANTGARDE.jpg

160606-9image

画像がこの位置にある場合、<h:graphicImage url=”/images/#{car.model}.jpg”/>となります。urlに注意です。

previousnext

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

JSF2.2入門 第8回コンバータ


kanban8

katatsumuri入力値をコンバートする

数値、日付などユーザーが文字列で入力した情報を都合のよいデータ形式に自動的に変換してくれます。

leaf入力と出力兼用JSFページ

日付を入力して色々な形式で表示します。実行画面をみてもらったほうがいいですね。

20160608-1

入力の形式は指定しないといけません。このとおり入れてもらいます。送信ボタンを押すと3つのスタイルで表示されます。これは下のコードの青、緑、紫のところに対応しています。

入力値用のコンバータタグはh:inputTextタグの内側に置きます。表示用のコンバータタグはh:outputTextタグの内側に置きます。

f:convertDateTime dateStyle=”full” type=”date”は日付の形式dateStyleはfullで年月日表示、typeはdate、つまり時刻抜きの日にちだけ。

f:convertDateTime dateStyle=”full” timeStyle=”long” type=”both”はdateStyleはlongで時分秒まで、typeはbothなので日にちと時刻の両方です。

f:convertDateTime pattern=”EEEEEEEE, MMM d,yyyy” type=”date”はpatternで表示形式を自分で設定しています。次のセクションにこれらの記号は解説してありますのでご覧ください。

<h:form>
<h:panelGrid columns=”2″ styleClass=”grid1″ >
日付の入力(YY/MM/DD hh:mm):
<h:inputText value=”#{dateBean.theDay}”>
<f:convertDateTime dateStyle=”short” timeStyle=”short” type=”both”/>
</h:inputText>
fullスタイル:
<h:outputText value=”#{dateBean.theDay}”>
<f:convertDateTime dateStyle=”full” type=”date”/>
</h:outputText>
date timeスタイル:
<h:outputText value=”#{dateBean.theDay}”>
<f:convertDateTime dateStyle=”full” timeStyle=”long” type=”both”/>
</h:outputText>
パターン指定:
<h:outputText value=”#{dateBean.theDay}”>
<f:convertDateTime pattern=”EEEEEEEE, MMM d,yyyy” type=”date”/>
</h:outputText>
<h:outputText value=””/>
<h:panelGrid columns=”2″ styleClass=”grid1″ >
<h:commandButton type=”submit” value=”送信” styleClass=”bt”/>
<h:commandButton type=”reset” value=”リセット” styleClass=”bt”/>
</h:panelGrid>
</h:panelGrid>
</h:form>

leafパターン

patternで指定できるものはjava.text.SimpleDateFormatで定義されているものです。前の例ではEEEEEEEEとたくさんEを並べましたが、これは最大文字数を表しますので、もし1文字Eだと金曜日は「金」と表示されます。

文字 日付または時刻のコンポーネント 表示
G 紀元 Text AD
y 1996; 96
Y 暦週の基準年 2009; 09
M July; Jul; 07
w 年における週 Number 27
W 月における週 Number 2
D 年における日 Number 189
d 月における日 Number 10
F 月における曜日 Number 2
E 曜日の名前 Text Tuesday; Tue
u 曜日の番号 (1 = 月曜、…、7 = 日曜) Number 1
a 午前/午後 Text PM
H 一日における時 (0 – 23) Number 0
k 一日における時 (1 – 24) Number 24
K 午前/午後の時 (0 – 11) Number 0
h 午前/午後の時 (1 – 12) Number 12
m Number 30
s Number 55
S ミリ秒 Number 978
z タイムゾーン 一般的なタイムゾーン Pacific Standard Time; PST; GMT-08:00
Z タイムゾーン RFC 822 タイムゾーン -0800
X タイムゾーン ISO 8601 タイムゾーン -08; -0800; -08:00

leafマネージドビーン

特に変わったところはありませんが、次のとおりです。Dateのオブジェクトになっています。

@Named(value=”dateBean”)
@RequestScoped
public class DateBean {

Date theDay;

public DateBean() {
}

public Date getTheDay() {
return theDay;
}

public void setTheDay(Date theDay) {
this.theDay = theDay;
}
}

leafほかのコンバータ

数字用のコンバータとしてf:convertNumberがあります。currencyCodeプロパティで通貨として扱ったり、maxFractionDigitsで小数点以下の桁数指定、maxIntegerDigitsで最大の整数範囲、patternでパターン指定などができます。

またf:converter タグというものもあって、自分自身でまるっきり新しいコンバータをカスタムメイドして使うこともできます。

previousnext

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

JSF2.2入門 第7回バリデーション


kanban7

katatsumuriバリデーション

バリデーションとはユーザーからの入力値をチェックすることです。入力値は間違えることがよくあるのでそのまま後の処理に入ってしまうとエラーが発生しますのでチェックは重要です。

サーブレットだけで組む場合には、エラーチェックを自分で作らなければなりませんがJSFには組み込まれたものがありますので便利です。

leaf必須入力

h:inputTextタグなど一連の入力タグにはrequiredプロパティが用意されていて、これをtrueにすると必須入力要素となります。もし入力されないとマネージドビーンに値はセットされませんし、次のページにも進みません。

ラジオボタンなら次のようになります。

<h:selectOneRadio value=”#{answerBean.gender}” required=”true”>
<f:selectItem itemValue=”男性” itemLabel=”男性”/>
<f:selectItem itemValue=”女性” itemLabel=”女性”/>
</h:selectOneRadio>

ラジオボタンはデフォルトでどっちか初期選択しておかないと未入力になりやすい要素です。

leaf数値の範囲

数値を受け取るための要素はh:inputTextです。これをセパレート型のタグにして間にバリデーション用のタグを置きます。

<h:inputText value=”#{answerBean.brand}”>
<f:validateLongRange minimum=”1″ maximum=”6″/>
</h:inputText>

このf:validateLongRangeタグはh:inputText タグに入力された整数の範囲をチェックするものです。 minimumには最小値、maximumには最大値をセットします。片方だけを指定することもできます。

このほか浮動小数の数値範囲をチェックするためのf:validateDoubleRangeタグもあります。

leaf文字数

文字数のチェックはf:validateLengthタグを使います。minimumかmaxmumの片方指定もできます。

4文字以上10 文字以下でユーザーID をどうぞ:
<h:inputText id=”user” value=”#{sampleBean.sometext}”>
<f:validateLength minimum=”4″ maximum=”10″/>
</h:inputText>

leaf

例として必須入力と整数範囲をやってみます。つぎのようなフォームでもしラジオボタンも数字も入力せずに送信ボタンを押すと画面のように下にメッセージが出ます。

160605-1err1

このメッセージはJSFに組み込まれているものです。また、ラジオボタンは選択されているが入力数値が7で範囲外になっている場合は

1605-2err2

日本語が少し変ですが意味はわかります。(メッセージ変更もめんどうですがやればできます)

このソースコードは次のとおりです。洋服ブランド名はマネージドビーンから情報を取り出して表示しています。これは次のセクションでちょっと説明します。

[validation.xhtml]・・・入力ページ

・・・
<h2>アンケートへご協力ください</h2>
・・・
<h:outputText value=”性別”/>
<h:panelGrid columns=”1″>
<h:selectOneRadio value=”#{answerBean.gender}” required=”true”>
<f:selectItem itemValue=”男性” itemLabel=”男性”/>
<f:selectItem itemValue=”女性” itemLabel=”女性”/>
</h:selectOneRadio>
・・・
<h:outputText value=”好きな洋服ブランド”/>
・・・
<ol>
<ui:repeat var=”item” value=”#{answerBean.brandList}”>
<li type=”1″>#{item}</li>
</ui:repeat>
</ol>
<h:inputText value=”#{answerBean.brand}”>
<f:validateLongRange minimum=”1″ maximum=”6/>
</h:inputText>
・・

[questionnaireResult.xhtml]

・・・

<h:panelGrid styleClass=”grid1″ columns=”2″>
<h:outputText value=”【回答】”/>
<h:outputText value=””/>
<h:outputText value=”性別: ”/>
<h:outputText value=”#{answerBean.gender}”/>
<h:outputText value=”好きなブランド: ”/>
<h:outputText value=”#{answerBean.brandName}”/>
</h:panelGrid>

・・・

正常に実行されると次のように表示されます。

160605-3result

leafマネージドビーンの工夫

前の画像で「好きなブランド」の回答が数字ではなく名前になっていますが、これはビーンに少し工夫を加えました。

まず配列brandListでブランド名を用意しておきます。アンケートのブランド名表示のころはui:repeatタグでgetBrandList()メソッドが自動的にコールされますから、このブランド名配列が返されるのです。ui:repeatタグはArrayListや配列を扱うことができます。

ユーザーからの情報はbrandプロパティに1から6の数字で入ってきますので、そのセッターであるsetBrand(String brand)メソッドのところで、数値をインデックスとしてbrandList配列から名前を参照してきて選択されたブランド名を入れる変数brandNameにセットします。結果のページでは#{answerBean.brandName}でこれを表示します。

[AnswerBean.xhtml]

・・・
public class AnswerBean {

String gender;
String brand;
String brandName;
final String[] brandList={“Marc Jacobs”,”EMODA”,”EGOIST”,”MURUA”,”dazzlin”,”その他”};

・・・
public void setBrand(String brand) {
this.brand = brand;
setBrandName(brandList[Integer.parseInt(brand)-1]);
}

public String getBrandName() {
return brandName;
}

public void setBrandName(String brandName) {
this.brandName = brandName;
}

public String[] getBrandList() {
return brandList;
}
}

leafまとめ

必須項目        <h:selectOneRadio …. required=”true”>
整数のチェック     f:validateLongRange
浮動小数のチェック  f:validateDoubleRange

previousnext

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

JSF2.2入門 第6回スタイルシート


kanban6

katatsumuriJSFにCSSを適用する

HTMLと同様にJSFコンポーネントにもスタイルシートを適用できます。スタイルシートを使うとリッチな表現ができますよね。

leafCSSの適用方法

スタイルはHTMLと同じで、適用する方法は2つあります。

  1. CSSファイルにスタイルを書いてそれを読み込む
  2. JSFファイルのHEAD部分にstyleタグでCSSを書く
  3. JSFタグの中のstyleプロパティに書く

leaf方法1:CSSファイルにスタイルを書いてそれを読み込む

たとえばこの画面のように、

  • フォーム全体に色を付ける
  • ボタンの文字を立体的に表示する
  • 入力欄にカーソルが置かれたらその欄の背景色を変える

160607-5style

160608-2style

CSSファイルは次のとおりです。ボールドで示した部分の5つのスタイルを設定しています。

  • BODYはフォントを設定しています。
  • tx1はテキスト入力欄で大きさや丸みを少し付けています。
  • tx1:focusはテキスト欄にカーソルが置かれたときに背景色を変えるようにしています。
  • grid1は前回学習したpanelGridコンポーネントの色を設定しています。
  • bt1はボタンにシャドーを付けたりしています。

[formStyle.css]

body{
font-family: “Hiragino Kaku Gothic ProN”,”メイリオ”, sans-serif;
font-size: 12pt;
}
.tx1 {
border-radius: 2px;
width: 300px;
height: 20px;
margin-top: 2px;
margin-bottom: 2px;
}
.tx1:focus {
background-color: #FFCCFF;
}
.grid1{
background-color: #00CCCC;
padding: 10px 20px 0px 20px;
margin: 5px;
}
.bt{
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0px 1px 2px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0px 1px 2px rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0px 1px 2px rgba(0, 0, 0, 0.2);
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
font-size: 13pt;
font-weight: bold;
text-shadow: 0px -2px 2px rgba(255, 255, 255, 0.8);
}

このCSSファイルはどこに置いても構いませんが、JSFページから参照しますから、そこからアクセスしやすいところがいいですね。整理しやすくするためにcssというディレクトリに入れたほうがよいと思います。配置はWebページの下にしましょう。

160608-1cssfile

JSFページでCSSを使うには次のように、h:head内でlinkタグ内でformStyle.cssを読み込みます。

JSFのタグの中にstyleClassプロパティがスタイルシートのセレクタとして機能しますので、それを使います。

[inputWithStyle.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”
xmlns:f=”http://xmlns.jcp.org/jsf/core”>
<f:view>
<h:head>
<title>User Registration and Navigation</title>
<link rel=”stylesheet” type=”text/css” href=”css/formStyle.css”/>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns=”2″ styleClass=”grid1″ >
お名前<h:inputText styleClass=”tx1″ value=”#{userInfoBean4.userName}”/>
生年月日(yyyy/MM/dd)<h:inputText styleClass=”tx1″ value=”#{userInfoBean4.birthDay}”/>
<h:panelGrid columns=”1″></h:panelGrid>
<h:panelGrid columns=”2″>
<h:commandButton type=”submit” styleClass=”bt” value=”送信” action=”result4″/>
<h:commandButton type=”reset” styleClass=”bt” value=”キャンセル” />
</h:panelGrid>
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>

この方法が一番よい方法だと思います。多くのページに共通で適用したり、ここに色々なスタイルを用意しておいて適当に適用していくといったことができます。あとでスタイル変更も1つのCSSの編集だけですから簡単ですね。

leaf方法2:JSFファイルのHEAD部分に書く

次のコードはHEAD部分だけを抜き出したのもですが、ここにstyleタグを使ってスタイルシートを書くこともできます。JSFのタグ側はさきほど同様にstyleClassを使います。

<h:head>
<title>User Registration and Navigation</title>
<style>
.grid1{
background-color: #00CCCC;
padding: 10px 20px 0px 20px;
margin: 5px;
}
</style>
</h:head>
<h:body>
・・・
<h:panelGrid columns=”2″ styleClass=”grid1″ >
・・・

この方法は、そのページだけに適用するCSSである場合やちょこっとした少量のCSSならばよい方法です。

また方法1で別のCSSファイルを読み込んで適用することを原則とするのだが、このJSFページだけはちょっと変更したいんだという場合には方法1と方法2を併用することもできます。同じセレクタ、ここではgrid1ですが、にはこのページで指定したスタイル設定が優先されます。それが「カスケード」という意味です。

leaf方法3:JSFタグの中に書く

タグの中にCSSを書き込んでしまう方法もあります。

その場合にはstyleClassでなくstyleプロパティを使います。HTMLタグと同じです。

<h:panelGrid columns=”2″ style=”background-color: #00CCCC;” >

この方法は方法1、2よりもさらに「個別」のスタイル設定方法です。ちょこっとしたスタイル設定に向いています。とにかくもっとも簡単な方法ですね。

leafまとめ

方法1: CSSファイルにスタイルを書いてそれを読み込む
【CSS設定】
<link rel=”stylesheet” type=”text/css” href=”css/formStyle.css”/>
【適用】
<h:panelGrid columns=”2″ styleClass=”grid1″ >

 

方法2: JSFファイルのHEAD部分にstyleタグでCSSを書く
【CSS設定】
<style>
.grid1{
background-color: #00CCCC;
padding: 10px 20px 0px 20px;
margin: 5px;
}
</style>
【適用】
<h:panelGrid columns=”2″ styleClass=”grid1″ >

 

方法3: JSFタグの中のstyleプロパティに書く
【CSS設定】【適用】
<h:panelGrid columns=”2″ style=”background-color: #00CCCC;” >

previousnext

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

JSF2.2入門 第5回様々な入力コンポーネント(2)

kanban5

katatsumuriチェックボックス・リストボックス・複数選択可プルダウンメニュー

今回はユーザーが複数の値を選べるコンポーネントについて説明します。前回の第3回と違うところは主にマネージドビーンの作りが違います。また表示ページも複数の値が表示できるように工夫が必要です。

leafまず画面イメージ

今回は音楽の趣味について聞いてみるようなアンケートページだと思ってください。要素は3つです。

  • ラジオボタン
  • リストボックス
  • プルダウンメニュー

リストボックスで色が濃くなっているところは選択されている項目です。1つ選択するにはクリックでいいですが、2つ目以降はCtrlキー+クリック、あるいはShft+クリックで連続領域が選択されます。

160607-3input

送信ボタンを押すと次のように入力された情報が表示されます。いくつ回答があるかわからないので工夫が必要です。

160607-4output

leaf入力ページ

チェックボックスはh:selectManyCheckboxを使います。リストボックスはh:selectManyListboxを使います。プルダウンメニューはh:selectManyMenuです。selectMenyという言葉が共通していることに気付きましたか?f:selectItemで選択肢を与えることは前回と同様です。h:selectManyListboxのsizeは同時にいくつの選択肢を見えるようにするか、つまり、行数を指定するものです。

送信ボタンを押すとcomponents2Result.xhtmlに移動します。

[components2.xhtml]

・・・省略・・・
<h:body>
<h2>Welcome to Music Agency</h2>
<hr width=”500″ align=”left”/>
<h:form>
<h:panelGrid id=”pg1″ columns=”1″>
<h:outputText value=”好きな音楽ジャンル: ”/>
<h:selectManyCheckbox value=”#{musicBean.type}”>
<f:selectItem itemValue=”J-POP” itemLabel=”J-POP”/>
<f:selectItem itemValue=”ロック” itemLabel=”ロック”/>
<f:selectItem itemValue=”ポップス” itemLabel=”ポップス”/>
<f:selectItem itemValue=”R&B” itemLabel=”R&B”/>
<f:selectItem itemValue=”ジャズ” itemLabel=”ジャズ”/>
<f:selectItem itemValue=”クラシック” itemLabel=”クラシック”/>
</h:selectManyCheckbox>
<h:outputText value=”好きな歌手: ”/>
<h:selectManyListbox size=”6″ value=”#{musicBean.musician}”>
<f:selectItem itemValue=”Ariana Grande” itemLabel=”Ariana Grande”/>
<f:selectItem itemValue=”Taylor Swift” itemLabel=”Taylor Swift”/>
<f:selectItem itemValue=”Justin Bieber” itemLabel=”Justin Bieber”/>
<f:selectItem itemValue=”Sam Smith” itemLabel=”Sam Smith”/>
<f:selectItem itemValue=”Bruno Mars” itemLabel=”Bruno Mars”/>
</h:selectManyListbox>
<h:outputText value=”好きなコンサート会場: ”/>
<h:selectManyMenu value=”#{musicBean.hall}”>
<f:selectItem itemValue=”日本武道館” itemLabel=”日本武道館”/>
<f:selectItem itemValue=”東京国際フォーラム” itemLabel=”東京国際フォーラム”/>
<f:selectItem itemValue=”東京ドーム” itemLabel=”東京ドーム”/>
<f:selectItem itemValue=”東京オペラシティ” itemLabel=”東京オペラシティ”/>
<f:selectItem itemValue=”サントリーホール” itemLabel=”サントリーホール”/>
</h:selectManyMenu>
<h:panelGrid id=”pg2″ columns=”2″>
<h:commandButton type=”submit” value=”送信” action=”components2Result” />
<h:commandButton type=”reset” value=”キャンセル” />
</h:panelGrid>
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>

leafマネージドビーン

入力ページから情報を受け取るプロパティはArrayListクラスにします。これは複数の値を受け取れるようにするためです。3つのプロパティを用意したら、それらのゲッターとセッターを用意するだけです。

[MusicBean .java]

package com.myjsf;

import java.util.ArrayList;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;

@RequestScoped
@Named
public class MusicBean {
ArrayList type;//ジャンル
ArrayList musician;//歌手
ArrayList hall;//コンサートホール

public MusicBean() {
type=new ArrayList();
musician=new ArrayList();
hall=new ArrayList();
}

public ArrayList getType() {
return type;
}

public void setType(ArrayList type) {
this.type = type;
}

public ArrayList getMusician() {
return musician;
}

public void setMusician(ArrayList musician) {
this.musician = musician;
}

public ArrayList getHall() {
return hall;
}

public void setHall(ArrayList hall) {
this.hall = hall;
}
}

leaf表示ページ

3つの情報表示とも同じテクニックを使っています。ui:repeatタグを使ってArrayList型のプロパティを受け取って、その要素があるだけ繰り返して表示します。そのvarプロパティの値にArrayListから1つずつのデータが取り出され、<span>#{eachData} / </span>というような方法で、その値を逐次表示します。/は単に表示を見やすくするための区切子です。

[component2Result.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”
xmlns:ui=”http://xmlns.jcp.org/jsf/facelets“>
<h:head>
<title>いただいた情報</title>
</h:head>
<h:body>
<h:panelGrid columns=”2”>
<h:outputText value=”【入力情報】”/>
<h:outputText value=””/>
<h:outputText value=”好きな音楽ジャンル: ”/>
<ui:repeat var=”eachData” value=”#{musicBean.type}”>
  <span>#{eachData} / </span>
</ui:repeat>
<h:outputText value=”好きな歌手: ”/>
<ui:repeat var=”eachData” value=”#{musicBean.musician}”>
  <span>#{eachData} / </span>
</ui:repeat>
<h:outputText value=”好きなコンサート会場: ”/>
<ui:repeat var=”eachData” value=”#{musicBean.hall}”>
  <span>#{eachData} / </span>
</ui:repeat>
</h:panelGrid>
</h:body>
</html>

leafまとめ

チェックボックス =h:selectManyCheckbox

リストボックス =h:selectManyListbox

プルダウンメニュー =h:selectManyMenu

を使う。

マネージドビーンのプロパティはArrayListクラスを使う。

表示にはui:repeatタグを使う。

previousnext

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

JSF2.2入門 第4回様々な入力コンポーネント(1)


kanban4

katatsumuriテキストエリア・ラジオボタン・プルダウンメニュー

JSFの基本入力コンポーネントはHTMLと同じものが用意されています。今回は入力値が1つしかないパターンについて解説します。チェックボックスなどは複数選べるので次の第5回で紹介します。なお、カレンダーで入力するものもネット上では見かけますが、これもJSFで作ることができますが標準では用意されていません。これらのリッチなコンポーネントを使いたい場合にはPrimeFacesやRichFacesといったJSFを使ったライブラリを使います。PrimeFacesは別の機会に紹介します。

leafここで作る画面のイメージ

まずはここで作る画面イメージを先に見てもらったほうが理解しやすいと思います。旅行会社の問い合わせページのように、行きたい地域、やってみたいこと、ご要望、を入力してもらいます。

160607-1input

入力コンポーネントは次の3つがあります。これらは1つしか値を選ぶことができませんのでマネージドビーンもそれを前提にして作ります。

  • プルダウンメニュー
  • ラジオボタン
  • テキストエリア

送信ボタンを押すとこのフォームが送られて、送信された情報を埋め込んだ次のページが表示されます。

160607-2output

leaf入力用JSFページ

1.プルダウンメニュー

これを作るのはh:selectOneMenuです。valueには入力値を受け取るプロパティを指定します。f:selectItemタグは選択肢をセットするものです。itemValueは送信される値でitemLabelは表示される値です。

2.ラジオボタン

これはh:selectOneRadioで作ります。valueには入力値を受け取るプロパティを指定します。内側にf:selectItemタグを入れることは同じです。

3.テキストエリア

h:inputTextarea を使います。colsには横の文字数。rowsには行数を指定します。valueには入力値を受け取るプロパティを指定します。

h:commandButtonのactionプロパティにはcomponents1Resultが指定されていますのでボタンが押されるとcomponents1Result.xhtmlが表示されて、入力された情報が表示されます。

[components1.xhtml]

・・・省略・・・
<h:body>
<h2>Welcome to Travel Agency</h2>
<hr width=”550″ align=”left”/>
<h:form>
<h:panelGrid id=”pg1″ columns=”2″>
<h:outputText value=”行きたい地域を選んでください: ”/>
<h:selectOneMenu id=”area” value=”#{travelBean.area}”>
<f:selectItem itemValue=”ヨーロッパ” itemLabel=”ヨーロッパ”/>
<f:selectItem itemValue=”アメリカ” itemLabel=”アメリカ”/>
<f:selectItem itemValue=”アジア” itemLabel=”アジア”/>
</h:selectOneMenu>
<h:outputText value=”旅行でやってみたいこと: ”/>
<h:selectOneRadio id=”purpose” value=”#{travelBean.purpose}”>
<f:selectItem itemValue=”観光” itemLabel=”観光”/>
<f:selectItem itemValue=”ショッピング” itemLabel=”ショッピング”/>
<f:selectItem itemValue=”スポーツ” itemLabel=”スポーツ”/>
</h:selectOneRadio>
<h:outputText value=”何かご要望がありましたらどうぞ: ”/>
<h:inputTextarea id=”comment” cols=”40″ rows=”5″ value=”#{travelBean.comment}”/>

<h:outputText value=””/>
<h:panelGrid id=”pg2″ columns=”2″>
<h:commandButton type=”submit” value=”送信” action=”components1Result” />
<h:commandButton type=”reset” value=”キャンセル” />
</h:panelGrid>

</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>

ここでh:panelGridタグについて説明しておきましょう。これは表示を整えるために使います。結果的にはHTMLのtableタグになり、表を使った整然とした配置を作ります。このタグのcolumns=”2″というのが便利なところで、2列の表を作ることを設定しています。

h:panelGridタグの内側に現れるh:outputTextやh:selectOneMenuなど各コンポーネントを左上から右下に向かって、出現する順番で2個ずつ自動的に並べてくれるのです。最後の行はちょっと変わっていますが、送信ボタンとリセットボタンはユーザーの操作手順から言って右下にあるのが自然です。ですから下の図で4行1列のところにはダミーで何も表示しないh:outputTextを入れています。4行2列のところはボタンが2個のままだとresetボタンが次の行に行ってしまうので、h:panelGridを1つつくってまとめて、h:panelGridの入れ子にしています。このタグをうまく使うと綺麗に並べることができます。

panelGrid

leafマネージドビーン

3つのプロパティarea、purpose、commentをString型で用意して、そのゲッター、セッターを用意するだけです。簡単です。

[TravelBean.java]

package com.myjsf;

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

@Named
@RequestScoped
public class TravelBean {

String area;//地域
String purpose;//何をしたいか
String comment;//要望

public TravelBean() {
}

public String getArea() {
return area;
}

public void setArea(String area) {
this.area = area;
}

public String getPurpose() {
return purpose;
}

public void setPurpose(String purpose) {
this.purpose = purpose;
}

public String getComment() {
return comment;
}

public void setComment(String comment) {
this.comment = comment;
}
}

leaf表示用のページ

次のように3つのh:outputTextタグを使って入力された情報を表示しています。

[components1Result]

・・・省略・・・

<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:h=”http://xmlns.jcp.org/jsf/html”>
<h:head>
<title>いただいた情報</title>
</h:head>
<h:body>
<h:panelGrid columns=”2″>
<h:outputText value=”【入力情報】”/>
<h:outputText value=””/>
<h:outputText value=”行きたい地域: ”/>
<h:outputText value=”#{travelBean.area}”/>
<h:outputText value=”旅行でやってみたいこと: ”/>
<h:outputText value=”#{travelBean.purpose}”/>
<h:outputText value=”コメント: ”/>
<h:outputText value=”#{travelBean.comment}”/>
</h:panelGrid>
</h:body>
</html>

leafまとめ

1.プルダウンメニュー =h:selectOneMenu

2.ラジオボタン =h:selectOneRadio

3.テキストエリア =h:inputTextarea 

選択肢はf:selectItemを使う。

表示を整えるにはh:panelGridタグを使う。columnsに列数を指定すれば、あとは自動的に並べてくれる。

previousnext

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

JSF2.2入門 第3回ページ移動

kanban3

katatsumuriシンプルなページ移動

leaf入力ページ

第2回目の「ユーザー入力」では入力ページと出力ページが同じものでした。ここでは入力と出力を別のページで行うようにします。ページ移動コントロールは「ナビゲーション」とも呼ばれます。

まず入力用のJSFページをinput1.xhtmlとして作ります。入力要素は名前と生年月日で変更ありませんが、h:commandButtonactionプロパティを追加します。値はresult1としました。ボタンが押されたら、ここに書いた文字列に.xhtmlという拡張子を加えたJSFページ、つまり「result1.xhtml」に移動するルールになっています。とても単純なルールです。

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

leaf出力ページ

出力ページは、さきほど説明したとおりresult1.xhtmlです。ここではh:outputTextでマネージドビーンから名前と生年月日を取得して表示しているだけです。

[result1.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”
xmlns:f=”http://xmlns.jcp.org/jsf/core”>
<f:view>
<h:head>
<title>Your Info</title>
</h:head>
<h:body>
<h2>入力情報</h2>
お名前:<h:outputText value=”#{userInfoBean.userName}”/><p/>
生年月日:<h:outputText value=”#{userInfoBean.birthDay}”/>
</h:body>
</f:view>
</html>

leaf実行する

NetBeansのプロジェクトウインドウで、input1.xhtmlファイルを選択して右クリックし[ファイルの実行]を選択します。ブラウザーが立ち上がりページが表示されますので、なにか情報を入力して[送信]ボタンを押します。

160529-1input

そうするとresult1.xhtmlに移動して、入力された情報が表示されます。

160529-2out

この例はシンプルなものでしたが、普通は入力値に基づいて何か処理をしてから結果を別のページで表示するという構成になります。

katatsumuri入力内容で次のページを変更

次の例は入力情報に男性か女性かを聞くラジオボタンを追加して、それを判断して行先のページを決定します。つまり男性用ページと女性用ページに振り分けます。

leafマネージドビーンに男女情報を追加する

マネージドビーンに男性か女性かを判別するためのgenderというプロパティを1つ加えます。NetBeansで、さきほどのUserInfoBeansビーンをコピーしてペーストし、名前をUserInfoBeans2.に変更してからその中身を変更します。変更部分は次のようになります。

160529-0beans

変更と追加したところは太字のところです。マネージドビーンをコピーペーストするとクラス名は新しい名前を聞かれますが、赤い太文字の部分、@Namedアノーテーション内の文字列は自動的に変更されませんので変更し忘れないように気を付けてください。

[UserInfoBeans2]

・・・

@Named(value = “userInfoBean2“)
@SessionScoped
public class UserInfoBean2 implements Serializable {
String userName;
String birthDay;
String gender;

public UserInfoBean2() {
}
・・・

blic String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}
public String targetPage(){
if(gender.equals(“men”)){
return “resultForMen”;
}else{
return “resultForWemen”;
}
}
}

それからtargetPage()メソッドを用意します。これは性別情報genderの値によって、シンプルに男性なら「resultForMen」女性なら「resultForWemen」という文字列を返すものです。ここから返される値を送信ボタンのactionプロパティに入れればよいのです。actionプロパティの値+”.xhtml”のページに移動するルールですから。

genderはString型としましたが、booleanやintでも扱うことができますね。処理が変わってきますが。

leaf入力ページを少し変更する

さきほどの単純移動の例で作ったinput1.xhtmlをコピペしてinput2.xhtmlとします。そこのh:commandButtonだけを変更します。actionプロパティの値として、マネージドビーンUserInfoBeans2のtargetPage()メソッドから返される値を入れます。userInfoBean2.targetPageという書き方はビーンのプロパティを取得する意味とメソッドを実行する意味と2つあることを意識してください。

[input2.xhtml]

・・・
<h:commandButton type=”submit” value=”送信” action=”#{userInfoBean2.targetPage}”/>

・・・

leaf出力ページ

男性用のページはresultForMen.xhtmlです。女性用のページはresultForWemen.xhtmlです。違いは太文字のところだけで単純です。

[resultForMen.xhtml]

・・・

<h:body>
<h2>入力情報</h2>
男性ですね。<p/>
お名前:<h:outputText value=”#{userInfoBean2.userName}”/><p/>
生年月日:<h:outputText value=”#{userInfoBean2.birthDay}”/>
</h:body>

・・・
[resultForWemen.xhtml]

・・・

<h:body>
<h2>入力情報</h2>
女性ですね。<p/>
お名前:<h:outputText value=”#{userInfoBean2.userName}”/><p/>
生年月日:<h:outputText value=”#{userInfoBean2.birthDay}”/>
</h:body>

・・・

leaf実行する

次のページが表示されますので、何か入れて送信ボタンをおします。女性のラジオボタンが押されていることを見てください。

160529-3nav1

送信ボタンを押すとちゃんと女性用のページに移動しました。URL欄のところに着目ですが、移動したページのものではなく、入力ページのままになっている特徴があります。

160529-4nav2

leafまとめ

ページ移動は、h:commandButtonactionプロパティを追加することで実現できる。actionプロパティに書いた文字列に.xhtmlという拡張子を加えたJSFページ移動するルールである。actionプロパティの値は固定値でもいいし、マネージドビーンから返される値でもよい。後者の場合にはさまざまな処理を行って行先ページをダイナミックに変えることができ多彩なアプリに応用できる。

previousnext

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

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電子書籍リーダーのご案内