Webアプリケーション開発の雑学

# 知っていたら便利な雑学
今回は、JavaによるWebアプリケーション開発（MVC）を題材に、知っていたら開発効率が格段に上がる技術を紹介していきます。今回は、スコープ、Viewのタグの２点についてお話させていただきます。

# スコープの話
スコープというのは、結論から述べると、データ（変数やオブジェクト）が保持される範囲（有効期間とアクセス範囲）のことを指します。たとえば、ユーザーがWebページを操作している間に保持される情報（ログイン情報や一時的な入力値など）を、どこまでの範囲・時間で使えるようにするかを決める仕組みです。スコープには、４つの種類があります。

下記のように並べていくと、４つのスコープがあり、左から右に向かっていく程、スコープが広くなります。

#### 狭　ページ→リクエスト→セッション→アプリケーション　広

今回は、コーディングをする上で、特に重要なリクエストスコープとセッションスコープについてお話します。

### リクエストスコープ
クライアントから入力されたデータが送信されて、サーバからクライアントにレスポンスが返ってくるまでを1リクエストとして、その1リクエスト中の範囲の中でデータを参照できます。例としては、ログインフォームでIDとパスワードを送信し、ログイン後に「ようこそ〇〇さん」と名前を表示するようなケースでは、

1.ログイン画面で、ログイン情報を入力して、ログインボタンをクリックする。（リクエスト送信）

2.サーブレットで、リクエストオブジェクトからIDとパスワードを取得してログイン処理を行う。
<pre>
    //サーブレット
    //リクエストスコープからIDとパスワードを取得
    String userId = request.getParameter("userId");
    String password = request.getParameter("password");
</pre>

3.ログイン処理成功後、ログインした人の名前を取得して、リクエストスコープにセットする。
<pre>
    //サーブレット
    //リクエストスコープにユーザ名をセット
    request.setAttribute("userName", ユーザ名);
</pre>
4.ログイン成功画面で、「ようこそ{リクエストスコープの値}さん」の形式で表示する。
<pre>
    //JSP
    //request.getParameter("userName")と同義
    ようこそ、${requestScope.userName} さん！
</pre>


という流れになります。

### セッションスコープ
同じクライアント間の、複数のリクエスト/レスポンス（セッション）間で参照することができます。主にログイン状態を保持するために、使用することが多いです。例としては、ログイン中のユーザ名を全ての画面で表示できるようにしたいケース等で使用されます。

1.セッションに値をセットする時は、リクエストオブジェクトからセッションオブジェクトを取り出して、キーと値のセットで、格納します。
<pre>
    //サーブレット
    //セッションスコープにユーザ名をセット
    HttpSession session = request.getSession();
    session.setAttribute("userName", ユーザ名);
</pre>

2.セッションに格納された値は、1リクエストのレスポンスが終了しても、他のリクエスト内のサーブレットやJSPから参照できます。
<pre>
    //サーブレット
    //セッションスコープからユーザ名を取得
    HttpSession session = request.getSession();
    String userName = session.getAttribute("username");
</pre>
<pre>
    //JSP
    //session.getAttribute("username")と同義
    ${sessionScope.userName}
</pre>

# View（JSP）のタグの話
### ディレクティブタグ
このタグは、JSPファイル全体の環境を設定するためのタグになります。今回は、pageディレクティブタグと、taglibディレクティブタグについて紹介していきます。

#### pageディレクティブタグ
文字通り、JSPファイルのそのページについての環境設定を行っていきます。「属性="値"」という形式で設定情報を記述していきます。
<pre>
<%@ page import="java.util.*, search.entity.Employee"
         session="true"
         contentType="text/html ; charset=UTF-8" pageEncoding="UTF-8" %>
</pre>
| 属性 | 説明 |備考|
|:------|:------|:------|
|import|利用したい他のクラスやパッケージを宣言する。||
|session|セッションオブジェクトを使用するか否かを指定する。 |初期値はtrue|
|contentType|クライアント（ブラウザ）に対して返すデータの種類（MIMEタイプ）と文字エンコーディングを指定する。||
|pageEncoding|JSPファイルのエンコーディング方式を指定する。||


#### taglibディレクティブタグ
開発者がベンダーが、独自に開発した便利なタグ（タグライブラリ）を使用する時に設定するタグです。一般的に、使用するタグライブラリを宣言して、そのタグライブラリを使用する際のタグの文字を宣言します。

<pre>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
</pre>
| 属性 | 説明 |
|:------|:------|
|uri|使用するタグライブラリを識別するための文字列を指定する。|
|prefix|JSPでタグライブラリを使用する場合の接頭辞を指定する。|

### EL式
EL式とは、JSPの式をより簡潔に記述できる式言語です。式の結果や、リクエスト・セッションのパラメータを出力することができます。

#### 式の実行結果
演算式や評価式を記述することができます。
<pre>
${100 + 200}//実行結果 200
${100 <= 200}//実行結果 true
</pre>

#### パラメータの出力
こちらは、リクエストパラメータを出力している様子です。このようにサーブレット内のコードと比べるととても簡略化されていますよね。
<pre>
${param.id}

//サーブレット内の以下の記述と同じ
req.getParameter("id");
</pre>

#### スコープに格納されているオブジェクトの参照結果の出力
リクエストスコープやセッションスコープに格納されているオブジェクトやプロパティ変数の値を出力します。コードの例を見てみますと、「スコープ.オブジェクト.プロパティ」の形式でプロパティの値を出力していることがわかります。
<pre>
//リクエストスコープ
${requestScope.emp.id}

//セッションスコープ
${sessionScope.emp.id}
</pre>

### JSTL
こちらは、多くのWebアプリケーションで利用する共通機能を実装したタグライブラリとなっております。これを利用する際には、taglibディレクティブタグでタグライブラリを宣言する必要があります。ここでは、outタグをご紹介します。

<pre>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>

&lt;c:out value=&quot;${requestScope.emp.id}&quot; /&gt;
</pre>

こちらは、先程のEL式のスコープに格納されているオブジェクトの参照結果の出力とoutタグを組み合わせたものですが、こちらを組み合わせることによって、JavaScriptの処理等が送られてきた場合に、害を及ぼさないように特殊文字を普通の文字に変換することができます。セキュリティ上の観点から、このように、outタグとEL式を組み合わせて記述することが望ましいでしょう。

| 属性 | 説明 | 備考 |
|:------|:------|:------|
|value|スコープに格納されているオブジェクトの参照名を指定する||
|escapeXml|出力する値に特殊文字が含まれていた場合、エスケープ処理を行うか否か|初期値はtrue|
|default|出力結果がnullの場合に表示するデフォルト値を指定する|指定が無い場合は空文字|

# まとめ
今回は、スコープとView（JSP）のタグについてお話させていただきました。今回は、Javaを例にご紹介しましたが、他のプログラミング言語でも、Webであればスコープの理解は必要ですし、MVCフレームワークのViewの記述は、今回紹介したタグのように、文法を簡略化するために、クセの強い記述の仕方になりがちなので、Web開発をする人は、ぜひ覚えてください。