Print Friendly, PDF & Email

前回は、JavaBeansについて学びました。

今回は、ELとJSTLについて学びます。

なぜ、ELが必要なのか?

EL(Expression Language)はすでに少し見たように変数やJavaBeansクラスのプロパティ値など、指定された式の出力を行うための言語です。

ELを使えば型をそれほど意識しなくても済むようになり、デザイナーの方にJSPを扱ってもらいやすくなります。

ELは日本語では式言語と呼ばれることもあります。

JSTLなどの拡張タグライブラリと用いれば、プログラムの知識が少ない人でもJSPで条件分岐や繰り返しを実現することができるようになります。

ELの基本

基本的なELはこれまでにも出てきましたので、ここでは簡単に振り返りたいと思います。

ELとは

EL(Expression Language)とは、短いプログラムコードを記述することで式を評価したり、変数に値をセットしたり取り出したり、メソッドを実行できる技術です。
JSP2.0より導入されています。

https://docs.oracle.com/javaee/6/tutorial/doc/bnahq.html


EL式は以下の形で定義します。

ELの書式

${式}

この時、{}で囲まれた式を評価し、評価結果を最終的な結果とします。

${"Hello World"}
<br>
${'Hello World'}
<br>
${42 * 42}
<br>
I'm ${20 + 3} years old.
<br>
Hello World has ${"Hello World".length()} characters.
<br>
  • 文字列はシングルクォーテーション、ダブルクオーテーションどちらで囲みますか?
あなたの答え:

このELの場合は文字列をシングルクォーテーションでも囲むことができるという点が後でまた出てきます。

  • 数値は何で囲みますか?
あなたの答え:
  • ELを文字列の中に埋め込むことはできますか?
あなたの答え:
  • ELの中でメソッドを使うことはできますか?
あなたの答え:

ELの演算子

ここでは、ELで使う演算子を見ていきます。

ただし、JavaSEでも演算子はやってきましたのでここではEL特有の部分だけを押さえてください。

ELの算術演算子

ELの算術演算子は基本はJavaSEのときと同じと覚えてください。

${1+2}
<br>
${1-2}
<br>
${2*3}
<br>
${5/2}
<br>
${5%2}
<br>
${"Hello"+=" World"}
算術演算子演算内容式の例結果(値)
+足し算${1 + 2}3
-引き算${ 1 - 2 } -1
*掛け算${ 2 * 3 } 6
/割り算${ 5 / 2 }
%剰余(余りを求める)${ 5 % 2 } 1
表7.1

ELの関係演算子

関係演算子もJavaSEと同様です。

ただし、ELには別表記もあります。

別表記があるのはHTMLの中に入ったときにも関係演算子を見やすくするため、とお考えください。

「<」よりも「lt」の方がHTMLの中に入ったときに見やすいです。

関係演算子を表にまとめると以下のとおりです。

関係演算子 (別表記)説明式の例 (別表記) 結果(値)
== (eq)左辺と右辺が等しい${1 == 1} (1 eq 1)true
!= (ne) 左辺と右辺が等しくない${1 != 2 } (1 ne 1) true
> (gt) 左辺が右辺より大きい${ 1 > 2 } (1 gt 1) false
< (lt) 左辺が右辺より小さい${ 1 < 2 } (1 lt 1) true
>= (ge) 左辺が右辺以上である${ 1 >= 2 } (1 ge 1) false
<= (le) 左辺が右辺以下である${ 1 <= 2 } (1 le 1) true
emptynullまたは空文字である${empty ""}
${empty null}
true
表7.2

ここではELの場合は==で文字列の比較ができることを知っておきましょう。(JavaSEではequalsメソッドを使う必要がありました)

なお、別表記の英語の意味は以下のとおりです。

eq:equal

ne:negate

gt:grater than

lt:less than

ge:grater than or equal to

le:less than or equal to

余裕があれば、覚えましょう。

他の言語でも使われる表現(例えばLinuxのシェルスクリプト)ですから覚えておいて損はありません。

使用例を以下のサンプルプログラムで示します。

${1 > 2}
<br>
${1 < 2}
<br>
${1 >= 2}
<br>
${1 <= 2}
<hr>
${1 eq 1}
<br>
${1 ne 2}
<br>
${1 gt 2}
<br>
${1 lt 2}
<br>
${1 ge 2}
<br>
${1 le 2}
<br>
${empty ""}
<br>
${empty null}
<br>
${empty "Hello"}
<hr>
${1 eq 1 && 2 eq 1}    
<br>
${1 eq 1 and 2 eq 1}
<br>
${1 eq 1 || 2 eq 1}    
<br>
${1 eq 1 or 2 eq 1}
<br>
${!(1 eq 1)}    
<br> 
${not(1 eq 1)}      

ELの論理演算子

論理演算子も基本はJavaSEと同じと考えて大丈夫です。

${1 eq 1 && 2 eq 1}    
<br>
${1 eq 1 and 2 eq 1}
<br>
${1 eq 1 || 2 eq 1}    
<br>
${1 eq 1 or 2 eq 1}
<br>
${!(1 eq 1)}    
<br> 
${not(1 eq 1)}   

論理演算子を表にまとめると以下のとおりです。

演算子 (別表記)読み方式がtrueになる条件使用例 (別表記)
&& (and)かつ AND左辺と右辺の両方がtrue${1 eq 1 && 2 eq 1} (${1 eq 1 and 2 eq 1})
|| (or)または ORすくなくとも左辺と右辺のどちらかがtrue${1 eq 1 || 2 eq 1} (${1 eq 1 or 2 eq 1})
! (not) 否定 NOT条件式がfalse ${${!(1 eq 1)} (${not(1 eq 1)})
表7.3

ELとJavaBeans

前回のJavaBeansとELは相性がいいです。

ELを使うと JavaBeansのプロパティを簡単に出力できます

ただし、その前に少し補足説明です。

このあとしばらくコード量を減らして見やすくするためにスクリプトレットを使います

この章では、MVCパターンの原則を破ってスクリプトレットを使います。

理由は、見易さのためです。

サーブレットとJSPを使った本来のWebアプリケーションの書き方ですと以下のようにファイルが2つに別れるうえにコード量も増えます。

package p07;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "WasteServlet", urlPatterns = {"/WasteServlet"})
public class WasteServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setAttribute("message", "Hello World");
        
        request.getRequestDispatcher("07JSTL/sample.jsp").forward(request, response);
    }
}
${message}

スクリプトレットを使えば上記の記述が以下のようになります。

ファイルが1つにまとめられる上にコード量が減って見易くなります。

<%
 request.setAttribute("message", "Hello World");
%>

${message}

よってこの章のみスクリプトレットを使うことをご了承ください。

リクエスト属性に入っているJavaBeansのデータをELで表示する

さて、JavaBeansをリクエスト属性に入れて、ELで取り出す方法を見てみましょう。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="p06.CustomerBean"%>
<%

    CustomerBean cb1 = new CustomerBean();
    cb1.setCustomerId(1);
    cb1.setName("今井");

    request.setAttribute("customer1", cb1);

    CustomerBean cb2 = new CustomerBean();
    request.setAttribute("customer2", cb2);

%>

${customer1}
<br>
${customer1.getName()}
<br>
${customer1.name}
<hr>
${customer2.name}
  • 16行目のように(リクエスト)属性名を指定すると何が出力されますか?
あなたの答え:
  • 18行目のように(リクエスト)属性名に続けてメソッドを呼び出すとどうなりますか?
あなたの答え:
  • 20行目のように(リクエスト)属性名に続けてプロパティを呼び出すとどうなりますか?
あなたの答え:
  • 22行目のようにnullのオブジェクトをELに入れるとどうなりますか?
あなたの答え:

このように、nullのオブジェクトをELに入れると何も出力されません。(NullPointerExceptionは発生しません)

JavaSEを学んできた皆さんのようなエンジニアには違和感の残る仕様かもしれません。

しかし、JSPが表示を担当している点、JSPを扱うのがデザイナーである点を考えると納得できる仕様です。

うまく活用してください。

調べてみましょう

先程のexpression1.jspにはrequestという変数が宣言もなく使用されていました。

これはJSPの暗黙オブジェクトと呼ばれるものです。

余裕があればこの暗黙オブジェクトについて調べなさい。

調べたことのメモ:

JavaBeansの入れ子の例

次にBeanの中にBeanが入っている例、Beanの入れ子の例を見てみましょう。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="p06.CustomersBean"%>
<%@page import="p06.CustomerBean"%>
<%

    CustomerBean cb1 = new CustomerBean();
    cb1.setCustomerId(1);
    cb1.setName("今井");

    CustomerBean cb2 = new CustomerBean();
    cb2.setCustomerId(2);
    cb2.setName("田渕");
    
    CustomersBean csb = new CustomersBean();
    csb.addCustomer(cb1);
    csb.addCustomer(cb2);

    request.setAttribute("customers", csb);

%>

${customers}
<br>
${customers.getCustomerArrayList()}
<br>
${customers.customerArrayList}
<br>
${customers.customerArrayList[0].name}
<br>

  • 22行目のようにBeanの入ったBeanを指定すると何が出力されますか?
あなたの答え:
  • 24行目のようにBeanのメソッドを呼び出すと何が出力されますか?
あなたの答え:
  • 26行目のようにBeanのプロパティを呼び出すと何が出力されますか?
あなたの答え:
  • 28行目のようにBeanのプロパティの0番目のプロパティを呼び出すことはできますか?
あなたの答え:

このようにしてBeanのプロパティのプロパティにアクセスすることも可能です。

しかし、実際には Beanのプロパティのプロパティにアクセスする場合には次のJSTLの繰り返しを使いますので、そのとき理解いただければ結構です。

実験1

ELとコメントの関係

以下のコメントだけからなるJSPを実行するとどうなるでしょうか?

HTMLのソースまで見て来て確かめてみましょう。

<%@page contentType="text/html" pageEncoding="UTF-8"%>

        <!-- htmlのコメント  ${1 +2 } -->
        <%-- JSPのコメント ${1 +2 } --%>
実験結果のメモ:

JSTLとは何か?

JSTL【JSP Standard Tag Library】はその名の通り、JSP内でよく使われる機能をライブラリ【Library】としてまとめたものです。

先のELと組み合わせることで、スクリプトレットが不要になり、可読性・保守性が向上します。

JSTLはカスタムタグといって自分でタグを作るのともできます。

しかし、本新人研修では既に用意されているタグのみを使います。

しかもJSTLのうち2つ、Coreタグという核となる基本のタグとi18nタグ【Internationalization】(面白いネーミングですね)という表示形式に関わるタグのみ紹介します。

※本来 Internationalizationのタグは国際化に関するJSTLタグですが、本研修では表示形式を整える目的でのみ使用します。

JSTLの使い方

当社新入社員研修の環境では、JSPの1行目に以下のようにしてPrefixとURIを指定するだけでJSTLが使えるようになります。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

※Coreタグの例

JSTLのCoreタグの使い方

JSTLの Coreタグ を使って条件分岐と繰り返しができるようになりましょう。

なお、以前出てきた以下の2つのタグとその他の使用頻度が低めのコアタグについてはここでは説明を割愛しています。

<c:out> 値を安全に出力する

<c:redirect> リダイレクトする

なお、 Coreタグは全て <c:タグの種類> のように書きます。

条件分岐

JSTLで単純分岐を実現するには<c:if>タグを使います

<c:if>

<c:if>の書式

<c:if test = "判定条件">

真の場合の処理(HTMLを書けば出力される:以降同様)

</c:if>

HTMLと同じように開始終了タグでifのブロックを表現します。

私達は当たり前のようにJavaSEでブロックを表現するのに{}を使ってきました。

しかし、JSTLのようにブロックの開始と終了を何らかの単語で表現するプログラミング言語もたくさんあります。

今のうちに慣れておきましょう。

<c:if> のtest属性には判定条件をEL式を使って記述します。

JavaSEで次のような処理があるとします。

        if (true) {
            System.out.println(true);
        }
        
        if(1 < 2){
            System.out.println(true);
        }
        
        if(1 > 2){
            System.out.println(true);
        }

以下は同じ処理をJSPで実現したものです。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>if1</title>
    <body>
        <c:if test="${true}" >
            trueです。
        </c:if>
        <hr>
        <c:if test="${1 < 2}" >
            1 < 2です。
        </c:if>
        <hr>
        <c:if test="${1 > 2}" >
            1 > 2です。
        </c:if>
        <hr>
    </body>
</html>
  • 9~11行の出力結果を予想しなさい。
あなたの答え:
  • 13~15行の出力結果を予想しなさい。
あなたの答え:
  • 17~19行の出力結果を予想しなさい。
あなたの答え:


例題1

20歳以上であれば「酒を飲む」と表示するJSTLをコメントの位置に書き入れなさい。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>if2</title>
    </head>
    <body>
        <%
            request.setAttribute("age", 20);
        %>
        <%--(ここに書く)--%>
    </body>
</html>

なお、JSTLのコメントは<%-- コメント --%>のように記述します。

<c:if>タグではvar属性に変数名を指定すると、test属性に指定した条件式の判定結果のboolean値がその変数に格納されますので以降の判定条件にその変数を使うことができます。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>if2</title>
    </head>
    <body>
        <%
            request.setAttribute("count", 10);
            request.setAttribute("name", "imai");
        %>
        <c:if test="${count >= 10}" >
            count:<c:out value="${count}" />
        </c:if>
        <hr>
        <c:if test="${name == 'imai'}" var="flag" />
        imai?:<c:out value="${flag}" />
        <hr>
        <c:if test="${flag}" >
            imai
        </c:if>
        <hr>
        <c:if test="${!flag}" >
            imaiではない
        </c:if>
    </body>
</html>
  • 14~16行の出力結果を予想しなさい。
あなたの答え:
  • 18~20行の出力結果を予想しなさい。
あなたの答え:
  • 21~23行の出力結果を予想しなさい。
あなたの答え:
  • 25~27行の出力結果を予想しなさい。
あなたの答え:

JavaSEのif文はelse句を使って処理を分岐させることができました。

しかし、JSTLの<c:if>タグにはelseはありません。

JSTLで多岐分岐を実現する場合は<c:choose>タグを使います

<c:choose>

JSTLで多岐分岐を扱うには<c:choose>タグを使います。

<c:choose>タグ の中には複数の<c:when>タグと、ひとつの<c:otherwies>タグを含めることができます。

<c:choose>の書式

<c:choose>

<c:when test = 判定条件1> 判定条件1が真の場合の処理 </c:when>

<c:when test = 判定条件2> 判定条件2が真の場合の処理 </c:when>

<c:otherwise> 判定条件1,2がともに義の場合の処理 </c:otherwise>

</c:choose>

JavaSEのときに作成したBMI「体重kg/(身長m * 身長m )」を判定するプログラムを作成してみます。

JavaSEの場合は以下のようになりました。

package p07;

public class javaSESampleifelse {

    public static void main(String[] args) {

        double bmi = 70 / (1.7 * 1.7);

        if (bmi < 18.5) {
            System.out.println("低体重(やせ型)");
        } else if (bmi < 25) {
            System.out.println("普通体重");
        } else {
            System.out.println("肥満");
        }
    }
}

上記と同じことをJSTLで実現します。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <%
            request.setAttribute("bmi", 70/(1.7*1.7));
        %>
        <c:choose>
            <c:when test="${bmi < 18.5}">低体重(やせ型)</c:when>
            <c:when test="${bmi < 25}">普通体重</c:when>
            <c:otherwise>肥満</c:otherwise>
        </c:choose>
    </body>
</html>

例題2

次のJavaSEのプログラムと同様のことをJSTLを使って実現しなさい。

package p07;

public class Q2 {

    public static void main(String[] args) {

        int num = (int) (Math.random() * 101) % 9;

        if (num == 0) {
            System.out.println("大吉です");
        } else if (num == 1 || num == 2) {
            System.out.println("中吉です");
        } else if (num >= 3 && num <= 5) {
            System.out.println("小吉です");
        } else if (num == 6 || num == 7) {
            System.out.println("凶です");
        } else {
            System.out.println("大凶です");
        }
    }
}

また、switch文的な役割もこの<c:choose>タグが担います。

以下はJavaSEの血液型診断のプログラムです。

package p07;

public class javaSESampleSwitch {

    public static void main(String[] args) {
        char bloodType = 'A';
        switch (bloodType) {
            case 'A':
                System.out.println("慎重な性格");
                break;
            case 'B':
                System.out.println("大胆な性格");
                break;
            case '0':
                System.out.println("おおらかな性格");
                break;
            default:
                System.out.println("不思議な性格");
        }
    }
}

上記と同じことをJSTLで実現します。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <%
            request.setAttribute("bloodType", "A");
        %>
        <c:choose>
            <c:when test="${bloodType == 'A'}">慎重な性格</c:when>        <%--シングルクートで文字列を使った例--%>
            <c:when test='${bloodType == "B"}'>大胆な性格</c:when>        <%--ダブルクオートで文字列を囲んだ例--%>
            <c:when test='${bloodType eq "O"}'>おおらかな性格</c:when>    <%--eqを使った例--%>
            <c:otherwise>不思議な性格</c:otherwise>
        </c:choose>
    </body>
</html>

ここでのポイントは繰り返しになりますが、ELでは==で文字列が等しいかどうかの判定ができる点です。(JavaSEではequalsメソッドを使う必要がありました)

また、文字列はシングルクォーテーションまたはダブルクオーテーションで囲うのでした。(JavaSEではダブルクオーテーションのみで、シングルクオーテーションは文字型の場合でした)

さらに==をeqと書くこともできるのでしたね。(JavaSEではeqはありませんでした)

繰り返し

JSTLで繰り返しを実現するには<c:forEach>タグを使います

<c:forEach>の書式

<c:forEach>

繰り返したい処理

</c:forEach>

また、以下の属性を指定できます。

属性意味
varvariableの略。繰り返し処理される値が代入される変数の名前(省略可)
itemsコレクションフレームワークを指定すれば、var属性で1つ1つの要素を取り出すことができるようになる

リストを使った繰り返し

<c:forEach> はJavaSEの拡張for文に似た使い方ができます

例えば、リストに入れたれた4人の名前を拡張for文を使って表示するには以下のように書きました。

        List<String> names = new ArrayList<String>();
        names.add("今");
        names.add("國分");
        names.add("田渕");
        names.add("久保川");
        
        for (String name : names) {
            System.out.println(name);
        }

同じことをしているのが以下のサンプルコードです。

このときitems属性に指定できるのはリストなどのコレクションフレームワーク(や配列)のみであることに注意が必要です。

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>forEach2</title>
    </head>
    <body>

        <%
            List<String> names = new ArrayList<String>();

            names.add("今");
            names.add("國分");
            names.add("田渕");
            names.add("久保川");

            request.setAttribute("names", names);
        %>

        <c:forEach var="name" items="${names}">            
            ${name}<br>
        </c:forEach>

        <c:forEach var="name" items="${names}">            
            ${name}:${name.length()}文字<br>
        </c:forEach>    

    </body>
</html>
  • 28~30行の出力結果を予想しなさい。
あなたの答え:

例題3

上記のプログラムをできるだけ何も見ないで自分自身で書きなさい。

オブジェクトを使った繰り返し

items属性に指定できるのはリストなどのコレクションフレームワークのみでした。

逆に言えばコレクションフレームワークであれば、その中身がどのようなオブジェクトでも指定できるということです。

<%@page import="p06.CustomersBean"%>
<%@page import="p06.CustomerBean"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>forEach3</title>
    </head>
    <body>

        <%
            CustomerBean c1 = new CustomerBean();

            c1.setCustomerId(1);
            c1.setName("今井");
            c1.setPrefectureId(23);
            c1.setAddress("愛知県一宮市一丁目");
            c1.setBirthday("1992-01-16");
            c1.setPoints(100);

            CustomerBean c2 = new CustomerBean();
            c2.setCustomerId(2);
            c2.setName("田渕");
            c2.setPrefectureId(23);
            c2.setAddress("三重県桑名市一丁目");
            c2.setBirthday("1995-06-13");
            c2.setPoints(100);

            CustomersBean csb = new CustomersBean();

            csb.addCustomer(c1);
            csb.addCustomer(c2);
            request.setAttribute("customers", csb);
        %>

        <c:forEach var="customer" items="${customers.customerArrayList}">            
            ${customer}<br>
        </c:forEach>
        <hr>
        <c:forEach var="customer" items="${customers.customerArrayList}">            
            ${customer.name}<br>
        </c:forEach>
        <hr>
        <table border="1">
            <thead>
                <tr>
                    <th>顧客ID</th>
                    <th>顧客名</th>
                    <th>都道府県コード</th>
                    <th>顧客住所</th>
                    <th>顧客誕生日</th>
                    <th>ポイント</th>
                </tr>
            </thead>

            <tbody>
                <c:forEach var="customer" items="${customers.customerArrayList}">    
                    <tr>
                        <td>${customer.customerId}</td>
                        <td>${customer.name}</td>
                        <td>${customer.prefectureId}</td>
                        <td>${customer.address}</td>
                        <td>${customer.birthday}</td>
                        <td>${customer.points}</td>
                    </tr>
                </c:forEach>
            </tbody>
        </table>
    </body>
</html>
  • 38~40行の出力結果を予想しなさい。
あなたの答え:
  • 42~44行の出力結果を予想しなさい。
あなたの答え:
  • 46~70行の出力結果を予想しなさい。
あなたの答え:

今回はスクリプトレットで2名分の顧客オブジェクトを用意して、それぞれのデータを出力しました。

もう少し学習が進むとデータベースから取り出した全員の顧客の情報をオブジェクトに入れて一覧表にして出力することもできるように成ります。

それまであと一息ですので頑張りましょう。

例題4

以下の例を参考に顧客リストのテーブルにあなたのチームメンバーを加えなさい。

ただし、住所や誕生日はダミーでよい。

単純な繰り返し

単純な繰り返しについては本研修では使用頻度が低いので以下の補講を見てください。

補講:JSTLをつかった単純な繰り返し

JSTLのi18nタグ

JSTLの i18nタグを使って金額や日付の表示フォーマットをコントロールできるようになりましょう。

例えば金額に3桁のカンマを付けたり、日付を和暦で表示したりといったことができるようになります。

当社が想定している最終課題をやり抜く上で特に重要なのが金額表示です。

金額の表示

例えば金額の先頭に¥マークを付けて3桁カンマ付きで金額を表示するには以下のようにします。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<fmt:formatNumber value="2590000" type="CURRENCY"  groupingUsed="true" />

結果を表示する

¥2,590,000

  • Coreタグを使用したときと何が同じで何が違いますか?
あなたの答え:

金額関連の属性としては以下を押さえれば十分です。

属性説明
typeデータ型 CURRENCYは金額の意で先頭に¥マークが付く、PERCENTは後ろに%が付く
groupingUsed3桁カンマの有無 trueは有り、falseは無し
maxFractionDigits小数部分の最大けた数(結果は四捨五入)
minFractionDigits小数部分の最小けた数 (結果は四捨五入)
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<fmt:formatNumber value="2590000" type="CURRENCY"  groupingUsed="true" /><br>

<fmt:formatNumber value="3.141592" maxFractionDigits="3"/><br>

<fmt:formatNumber value="0.12345" type="PERCENT" minFractionDigits="1"/><br>

<fmt:formatNumber value="0.23456" type="PERCENT" minFractionDigits="1"/><br>

結果を表示する

¥2,590,000
3.142
12.3%
23.5%

日付の表示

次に日付の表示をコントロールしてみます。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<jsp:useBean id="date" class="java.util.Date"/>

<%
    java.util.Date theDay = new java.util.Date();
    request.setAttribute("theDay", theDay);

%>

<html>
    <body>
        <h4><fmt:formatDate value="${theDay}" pattern="yyyy年MM月dd日(E)" /> </h4>
        <h4><fmt:formatDate value="${theDay}" pattern="yy年M月d日(E)" /></h4>
        <h4><fmt:formatDate value="${theDay}" pattern="yyyy年" /></h4>
        <h4><fmt:formatDate value="${theDay}" pattern="MM月" /></h4>
        <h4><fmt:formatDate value="${theDay}" pattern="dd日(E)" /></h4>
    </body>
</html>

結果の例を表示する

2022年01月07日(金)
22年1月7日(金)
2022年
01月
07日(金)

日付関連の属性にpatternがありますが、以下を押さえればこの研修では十分です。

pattern意味(一般に文字数が桁数を意味する)表示例
y西暦年(year)2022
M月(month)01
d日(day)07
E曜日()

なお、このパターンは多くのプログラミング言語やツール(例.EXCEL)でほぼ共通のものですから覚えて損はありません。

例題5

上記の例を参考に今日の日付をいろいろな表現で表示しなさい。

日付が文字列型である場合の注意点

1点注意点として、文字列は一度日付として解析し直さないといけない点にご注意ください。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
    
    request.setAttribute("dateString","2022-01-08");

%>
<html>
    <body>
        <fmt:parseDate var="date" value="${dateString}" pattern="yyyy-MM-dd" />
        <fmt:formatDate value="${date}" pattern="yyyy年M月d日" />
    </body>
</html>

この後データベース利用を学びますがMySQLで日付を文字列型で持たせるチームもあるかと思います。

上記10行目のようにして、一旦Dateとしてparse(解析)する必要がありますので事前にお知らせします。

最後に今回紹介したCoreタグとi18nタグについてまとめておきます。

種類Prefix URI
Corechttp://java.sun.com/jsp/jstl/core
Internationalization(i18n)fmthttp://java.sun.com/jsp/jstl/fmt

今回はELとJSTLについて学びました。

次回は、JDBCを学んでいきます。

JDBC を使えば、データベースから取り出したデータをBeansに入れて、<c:forEach>タグを使い拡張for文のような使い方をしてデータベースの内容を全てJSPに出力するということもできるようになります。

まとめ

□ ELの場合は文字列をシングルクォーテーションでも囲むことができる

□ ELは==で文字列の比較ができる

□ ELを使うと JavaBeansのプロパティを簡単に出力できる

□ nullのオブジェクトをELに入れると何も出力されない

□ JSTLで単純分岐を実現するには<c:if>タグを使う

□ JSTLで多岐分岐を実現する場合は<c:choose>タグを使う

□ JSTLで繰り返しを実現するには<c:forEach>タグを使う

□ <c:forEach>タグはJavaSEの拡張for文に似た使い方もできるが、items属性に指定できるのはリストなどのコレクションフレームワークのみである点に注意する

□ JSTLの i18nタグを使うと金額や日付の表示フォーマットをコントロールできる

JavaWebアプリケーション目次に戻る