JSF(JavaServer Faces)プロジェクトを利用して、JavaベースのWebアプリケーションを作成することができる。
今回は、入力画面・確認画面・完了画面の3画面を含み、HTMLオブジェクトとしてテキストボックス・ラジオボタン・チェックボックス等を含むWEBアプリケーションを作成してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事に記載した、JSFプロジェクトの作成が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は、以下の通り。
なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
web.xmlの内容は以下の通りで、初期表示画面をinput.xhtmlに設定し、テキスト・テキストエリアの文字化け防止用Filterを追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>demoJsf</display-name> <welcome-file-list> <!-- 画面遷移先でJSFタグを利用できるよう、Faces ServletのURL(faces/)を先頭に付与 --> <welcome-file>faces/input.xhtml</welcome-file> </welcome-file-list> <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>/faces/*</url-pattern> </servlet-mapping> <!-- JSFでのテキスト・テキストエリアの文字化け防止用Filterを設定 --> <filter> <filter-name>Encoding</filter-name> <filter-class>common.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-app> |
また、テキスト・テキストエリアの文字化け防止用Filterの内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package common; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * 文字コードをweb.xmlに記載したものに設定するためのフィルタ. */ public class EncodingFilter implements Filter { /** 文字コード */ private String encoding; @Override public void doFilter(ServletRequest request , ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(encoding); chain.doFilter(request, response); } @Override public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("encoding"); } @Override public void destroy() {} } |
さらに、入力画面(input.xhtml)、確認画面(confirm.xhtml)、完了画面(complete.xhtml)の内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?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:f="http://java.sun.com/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>入力画面</title> </h:head> <h:body> <p>下記必要事項を記載の上、「確認」ボタンを押下してください。</p><br/> <h:form> <table border="0"> <tr> <td align="left" valign="top">名前:</td> <td><h:inputText value="#{inputFormAction.name}" /></td> </tr> <tr> <td align="left" valign="top">生年月日:</td> <td> <h:inputText value="#{inputFormAction.birthYear}" size="4" maxlength="4" />年 <h:selectOneMenu value="#{inputFormAction.birthMonth}"> <f:selectItems value="#{inputFormAction.birthMonthItems}"/> </h:selectOneMenu>月 <h:selectOneMenu value="#{inputFormAction.birthDay}"> <f:selectItems value="#{inputFormAction.birthDayItems}"/> </h:selectOneMenu>日 </td> </tr> <tr> <td align="left" valign="top">性別:</td> <td> <h:selectOneRadio value="#{inputFormAction.sex}"> <f:selectItems value="#{inputFormAction.sexItems}"/> </h:selectOneRadio> </td> </tr> <tr> <td align="left" valign="top">メモ:</td> <td><h:inputTextarea value="#{inputFormAction.memo}" cols="40" rows="6" /></td> </tr> <tr> <td align="left" valign="top">入力確認:</td> <td><h:selectBooleanCheckbox value="#{inputFormAction.checked}" /></td> </tr> </table> <br/> <h:commandButton value="確認" action="#{inputFormAction.confirm()}" /> </h:form> </h:body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?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"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>確認画面</title> <h:outputStylesheet library="css" name="demoJsf.css"/> </h:head> <h:body> <p>入力内容を確認し、問題なければ「送信」ボタンを押下してください。</p><br/> <h:form> <table border="0"> <tr> <td align="left" valign="top">名前:</td> <td><h:outputText value="#{inputFormAction.name}" /></td> </tr> <tr> <td align="left" valign="top">生年月日:</td> <td><h:outputText value="#{inputFormAction.birthYear}年 #{inputFormAction.birthMonth}月 #{inputFormAction.birthDay}日" /></td> </tr> <tr> <td align="left" valign="top">性別:</td> <td><h:outputText value="#{inputFormAction.sexLabel}" /></td> </tr> <tr> <td align="left" valign="top">メモ:</td> <td><h:outputText value="#{inputFormAction.memo}" styleClass="lineBreakFormat" /></td> </tr> <tr> <td align="left" valign="top">確認チェック:</td> <td> <h:outputText value="確認済" rendered="#{inputFormAction.checked}" /> <h:outputText value="未確認" rendered="#{inputFormAction.checked == false}" /> </td> </tr> </table> <br/> <h:commandButton value="送信" action="#{inputFormAction.send()}" /> <h:commandButton value="戻る" action="#{inputFormAction.back()}" /> </h:form> </h:body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>完了画面</title> </h:head> <h:body> <p>お申し込みが完了しました。</p> </h:body> </html> |
また、各画面のForm値と画面遷移処理を定義したクラスの内容は以下の通りで、入力画面・確認画面から呼び出されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | package faces; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.SessionScoped; import javax.faces.model.SelectItem; import javax.inject.Named; import common.CommonUtil; /** * 画面のフォーム値と画面遷移メソッドを定義. */ // @Namedアノテーションは、JSFのXHTMLファイルから#{inputFormAction}で // Javaクラスを参照できるようにしている(→バッキングビーン) // @SessionScopedアノテーションは、このバッキングビーンの生存期間を // セッションに設定している @Named(value="inputFormAction") @SessionScoped public class InputFormAction implements Serializable { // シリアルバージョンUID private static final long serialVersionUID = 7283339629129432007L; /** 名前 */ private String name; /** 生年月日_年 */ private String birthYear; /** 生年月日_月 */ private String birthMonth; /** 生年月日_日 */ private String birthDay; /** 性別 */ private String sex; /** 性別(ラベル) */ private String sexLabel; /** メモ */ private String memo; /** 確認チェック */ private String checked; /** 生年月日_月(選択リスト) */ private List<SelectItem> birthMonthItems; /** 生年月日_日(選択リスト) */ private List<SelectItem> birthDayItems; /** 性別(選択リスト) */ private List<SelectItem> sexItems; /** * コンストラクタ生成時に選択リストの値を設定. */ public InputFormAction(){ // 生年月日_月(選択リスト) birthMonthItems = new ArrayList<SelectItem>(); birthMonthItems.add(new SelectItem("", "")); for(Integer i = 1; i <= 12; i++){ birthMonthItems.add(new SelectItem(String.valueOf(i), String.valueOf(i))); } // 生年月日_日(選択リスト) birthDayItems = new ArrayList<SelectItem>(); birthDayItems.add(new SelectItem("", "")); for(Integer i = 1; i <= 31; i++){ birthDayItems.add(new SelectItem(String.valueOf(i), String.valueOf(i))); } // 性別(選択リスト) sexItems = new ArrayList<SelectItem>(); sexItems.add(new SelectItem(String.valueOf(1),"男")); sexItems.add(new SelectItem(String.valueOf(2),"女")); } /** * 確認画面への遷移. * @return 確認画面へのパス */ public String confirm(){ // 性別(ラベル)を設定 if(!CommonUtil.isBlank(sex)){ this.setSexLabel(this.getSexItems() .get(Integer.parseInt(this.getSex())-1).getLabel()); } // Formに設定された値を出力 System.out.println(this.toString()); // 確認画面に遷移、ただし、遷移先URLを正しく表示し画面遷移を安定させるため、 // ?faces-redirect=trueを付与し、フォワードからリダイレクトに変更している return "confirm.xhtml?faces-redirect=true"; } /** * 入力画面に戻る. * @return 入力画面へのパス */ public String back(){ // 入力画面に戻る return "input.xhtml?faces-redirect=true"; } /** * 完了画面への遷移. * @return 完了画面へのパス */ public String send(){ // 確認画面に表示された値を出力 System.out.println(this.toString()); // 完了画面に遷移 return "complete.xhtml?faces-redirect=true"; } @Override public String toString() { return "InputForm [name=" + name + ", birthYear=" + birthYear + ", birthMonth=" + birthMonth + ", birthDay=" + birthDay + ", sex=" + sex + " sexLabel=" + sexLabel + ", memo=" + memo + ", checked=" + checked + "]"; } // 以下はGetter/Setterメソッド // JSFのXHTMLファイルから各メンバ変数にアクセスするために必要 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getBirthYear() { return birthYear; } public void setBirthYear(String birthYear) { this.birthYear = birthYear; } public String getBirthMonth() { return birthMonth; } public void setBirthMonth(String birthMonth) { this.birthMonth = birthMonth; } public String getBirthDay() { return birthDay; } public void setBirthDay(String birthDay) { this.birthDay = birthDay; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getSexLabel() { return sexLabel; } public void setSexLabel(String sexLabel) { this.sexLabel = sexLabel; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } public String getChecked() { return checked; } public void setChecked(String checked) { this.checked = checked; } public List<SelectItem> getBirthMonthItems() { return birthMonthItems; } public void setBirthMonthItems(List<SelectItem> birthMonthItems) { this.birthMonthItems = birthMonthItems; } public List<SelectItem> getBirthDayItems() { return birthDayItems; } public void setBirthDayItems(List<SelectItem> birthDayItems) { this.birthDayItems = birthDayItems; } public List<SelectItem> getSexItems() { return sexItems; } public void setSexItems(List<SelectItem> sexItems) { this.sexItems = sexItems; } } |
さらに、確認画面(confirm.xhtml)で読んでいるCSSファイル、共通ユーティリティクラスの内容は、以下の通り。
1 2 3 4 5 | .lineBreakFormat{ /* 改行コードをbrタグに変換し表示する */ /* 空白文字はそのまま残す */ white-space: pre; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package common; /** * 共通ユーティリティクラス. */ public class CommonUtil { /** * 引数で指定した文字列がNULL,空文字,空白のみかどうかをチェックする. * @param cs 文字列 * @return 判定結果 */ public static boolean isBlank(final CharSequence cs) { final int strLen = length(cs); if (strLen == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } /** * 引数で指定した文字列の長さを返却する. * @param cs 文字列 * @return 文字列の長さ */ public static int length(final CharSequence cs) { return cs == null ? 0 : cs.length(); } } |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/javaee-jsf-web-somescreen/demoJsf
サンプルプログラムの実行結果
サンプルプログラムの実行結果は以下の通り。
1) GlassFishサーバーを起動後、Webブラウザ上で「http:// (ホスト名):(ポート番号)/(Webアプリケーションのプロジェクト名)/」とアクセスする。
2) 以下のように、データを指定し「確認」ボタンを押下すると、確認画面に入力画面の内容が表示される。さらに「戻る」ボタンを押下すると、入力画面に戻り入力値が復旧されることが確認できる。
3) 以下のように、メモを入力しないで「確認」ボタンを押下した場合も、確認画面に入力画面の内容が表示される。さらに「送信」ボタンを押下すると、完了画面に遷移することが確認できる。
4) 2)3)の動作で、以下のように、コンソールに赤枠のログが出力されることが確認できる。
要点まとめ
- JSF(JavaServer Faces)プロジェクトを利用して、JavaベースのWebアプリケーションを作成することができる。
- JSFのXHTMLファイルからJavaクラスやメンバ変数を参照できるようにする(→バッキングビーンの生成)には、Javaクラスに@Namedアノテーションを付与し、メンバ変数のGetter/Setterメソッドを付与する必要がある。
- JSFのXHTMLファイルからバッキングビーンを参照するには、#{バッキングビーン名.メンバ変数}、#{バッキングビーン名.メソッド名()}というEL式を利用する。
- JSFのテキスト/テキストエリアの文字化けを防止するには、文字化け防止用のFilterを追加する。