独習Javaサーバサイド編第2版 第3章まとめ

リクエスト情報

クライアントからサーバに送信される情報の総称

HTTP通信の確認

HTTP通信の構成

要求
・HTTPメソッド:サーバに対する直接の要求と取得するパス
・リクエストヘッダ:リクエストの構成情報、クライアント情報など
・リクエスト本体:フォームから送信されたデータ
応答
・HTTPステータス:サーバでの処理結果を表すコードとメッセージ
・レスポンスヘッダ:コンテンツの構成情報、サーバ情報など
・レスポンス本体:コンテンツ本体

HTTPメソッド

クライアントからサーバに対して発行する直接の命令
メソッド名、パス、プロトコル情報から構成される
GETは指定されたコンテンツを取得しなさいという命令

HTTPステータス

サーバでの処理結果を表す
クライアントの処理方法や次のアクションを決める情報でもある
200 OK であれば、サーバでの処理が正しく終了し応答が返されたことを表す

ポストデータ

 

タグで定義されたHTMLフォームから送信されるデータのこと
テキストボックスやラジオボタン、選択ボックスなど、フォーム要素から入力された情報はサブミットボタンをクリックすることでサーバに送信される
クライアントから送信されたポストデータを取得するのはrequest.getParameterメソッドの役割
requestオブジェクトは暗黙オブジェクトのひとつで、ブラウザからサーバに送信されたリクエスト情報にアクセスするためのさまざまな機能を提供する
getParameterメソッドはその中でも最もよく利用されるメソッドのひとつで、指定された名前と合致するフォーム部品のデータを取得する
getParameterメソッド(requestオブジェクト)
String getParamete(String name)
name:名前
指定された名前に対応する値を取得する。名前は<input><select>タグなどで指定されたnameオプションの値

フォーム部品

テキストボックス

自由なテキストを入力するためのボックス
< input>タグのtypeオプションを変更することで用途に応じた専用のテキストボックスを作成できる
typeオプションのほか、sizeオプションでボックスの長さ、maxlengthオプションで入力できる最大文字列長、valueオプションでデフォルト値を指定できる
なお、nameオプションで指定された値はJSPJavaScriptなどのプログラムからフォーム部品の値を特定する際のキーとなる
プログラムからはnameオプションの値を指定することでその部品に入力された値を取り出すことができる

ラジオボタン(単一選択ボタン)

あらかじめ決められた選択肢から値を選ばせたいとき使用
原則としてひとつの選択肢にしか指定できない
グループとしてまとめるラジオボタン群にはnameオプションにも同じ名前をつける
checkedオプションを指定することでデフォルト値を指定できる非選択状態を選ばせたい場合、明示的に値がブランクの選択肢をひとつ作っておかなければならない

チェックボックス(複数選択ボタン)

複数選択が可能
一度選択したものも自由に解除可能
checkedオプションを複数のチェックボックスに指定することも可能
選択肢の中から複数のオプションを選ばせるだけでなく、単一の項目でON/OFFのような選択をさせる場合使用する

ドロップダウンメニュー(選択ボックス)

単一の選択しかできない
ボックスの中に選択肢が収められているので選択肢が多い場合使用
デフォルト値はselectedオプションで指定できる
非選択状態を選ばせたい場合、明示的に値がブランクの< option>タグを用意しなければならない

リストボックス(複数選択ボックス)

選択ボックスと異なるのは< select>タグにsizeオプションを指定している点
sizeオプションで指定された行数を持つリストボックスが作成される
画面上の領域は取るが、multipleオプションを付加することで複数選択ができるのが特徴

テキストエリア(複数行テキストボックス)

複数行の任意のテキストを入力する際に使用
rowsオプションで行数、colsオプションで桁数を指定
デフォルト値は< textarea>要素の本体として表すので、< textarea>と< /textarea>の間に余計な改行や空白をいれてはいけない
後からテキストエリアの入力値を処理する際にもテキストに含まれる改行文字を考慮しなければならない

スライダー

連続した数値を指定したい場合に利用
数値入力ボックスにも似ているがマウスドラッグで値を変更できることから操作しやすい、視覚的に大小を把握しやすいなどの特徴がある

隠しフィールド

やや特殊なフォーム部品
目に見えないフィールドであらかじめセットされた値をユーザが変更することはできない
システム制御の情報や複数ページにまたがって保持したい情報を受け渡しする場合に使用

日本語を扱う

JSP&サーブレットがデフォルトでリクエスト情報を欧米系の文字コードで処理しようとするため文字化けすることがある
リクエスト情報に日本語を含む可能性がある場合はrequest.setCharacterEncodingメソッドでリクエスト情報の文字コードを宣言しておく必要がある

setCharacterEncodingメソッド(requestオブジェクト)
void setCharacterEncoding(String enc) throws UnsupportedEncodingException
enc:文字コード
クライアントから送信されたリクエスト情報の文字コードを宣言する

文字コードは一箇所にだけ設定すれば終わりというものではなく、リクエスト情報、出力情報など対象に応じて設定する必要がある

setCharacterEncodingメソッドを使用する注意点

・getParameterメソッドよりも前に呼び出す
・JISAutoDetectは使わない

複数の値を持つ要素にアクセスする

getParameterメソッドは要素名に関連づけられた単一の値しか取得できない
同一の要素名に複数の値が関連付けられている場合、getParameterValuesメソッドを使用する

getParameterValuesメソッド(requestオブジェクト)
String[] getParameterValues(String name)
name:パラメータ名
指定された要素名に対応する値を文字列の配列として取得する
指定された要素が存在しない場合nullを返す

なお指定された要素の値がひとつしかない場合にもgetParameterValuesメソッドはその値を要素をひとつしか持たない文字列配列として返す

クエリ情報

URLの末尾の「〜?」以降に「キー名=値」のセットで付加される簡易な情報
ポストデータと並んで、クライアントからサーバに対して情報を渡すための基本的な方法のひとつ
パス本体とクエリ情報は「?」で区切られ、複数のキーがある場合&で連結される
URLに直接文字列として指定するほか< form>タグでGETオプションを指定した場合にもフォームに入力されたデータがすべてクエリ情報としてサーバに送信される
Tomcatではクエリ情報の解析に際してrequest.setCharacterEncodingメソッドで指定された文字コードを適用しないという使用になっている
この問題を解決するにはserver.xmlを編集する必要がある
sever.xmlを変種した際、Tomcatは必ず再起動させる

ハイパーリンク経由で値を受け渡しする

? & % 空白文字 マルチバイト文字などはクエリ情報に含められないのであらかじめ無害な文字列に変換しておく
このことをURLエンコードという
URLエンコードを行うのはURLEncoderクラスのencodeメソッドの役割である

encodeメソッド(URLEncoderクラス)
static String encode(String s,String enc) throws UnsupportedEncodingException
s:任意の文字列
enc:文字コード
文字列を指定された文字コードでURLエンコードする

ポストデータとクエリ情報

JSPではポストデータ/クエリ情報のいずれにもrequest.getParameterメソッドでアクセスできるのでアプリケーション開発者はこれを意識しなくてよい
しかし両者には違いがあるので用途によって使い分ける必要がある

クエリ情報

データをURLの一部として送信する

ポストデータ

リクエストボディと呼ばれるブロックに乗せてデータを送信する

クエリ情報で送信できるデータサイズには制限がある

ポストデータのデータサイズが事実上無制限なのに対して使用しているブラウザ環境から制約を受ける
URLの一部として送信されるクエリ情報は、パス本体との合計サイズでこの制限を超えることはできない
クエリ情報の最大サイズは数百バイト程度にとどめておくのが無難である

クエリ情報ではデータがアドレス欄に露出してしまう

しかしポストデータを使用したからといってデータが保護されるわけでもない
データを保護したいのであればSSL(Secure Socket Layer)のような暗号化通信を利用する必要がある

POST経由で得た結果をブックマークすることはできない

クエリ情報はデータをURLに付加する形で表現するのでその結果をブックマークできる(このような性質は検索エンジンなどで利用される)
ポストデータでは、URLとは別にリクエストボディとして送信されるので、ポストしたその結果をブックマークすることはできない

以上のことから

純粋にデータを受け渡しする手段としてはポストデータの方がクエリ情報よりも制約が少ない
クエリ情報はちょっとしたキーを受け渡しする手段としてシンプルで重要なデータ伝達の手段である(特に表示するページを識別するようなキー情報を受け渡す手段としてべんり)

ヘッダ情報

不可視情報のことを ヘッダ情報 (またはより限定して リクエストヘッダ情報 )という

内容による分類

・一般ヘッダ:要求/応答時双方で利用
・エンティティッヘッダ:コンテンツに関する情報
・リクエスト(要求)ヘッダ:クライアントに関する情報
・レスポンス(応答)ヘッダ:クライアントに関する情報でない
一般ヘッダ、エンティティヘッダは状況によってリクエスト情報/レスポンス情報いずれにも含まれる可能性がある

ヘッダ情報の利用方法

代表的なリクエストヘッダ

User-Agentヘッダ

サイトにアクセスしてきたクライアントの種類がわかる
アクセスログとして記録すればアクセスしてくるユーザの傾向がわかったり、検索エンジンのクローラ(巡回アプリケーション)がどの程度の頻度でサイトを巡回しているかわかる

Refererヘッダ

自サイトに対してどのようなページがリンクを張っているのか、自サイト内でユーザがどのようにページ間を移動しているか把握できる

Accept-Languageヘッダ

クライアントの対応言語を表す

代表的なレスポンスヘッダ

Content-Typeヘッダ

ページで使用している文字コードを表す

WWW-Authenticateヘッダ

クライアントに認証を要求できる

Locationヘッダ

クライアントを強制的に別のページへリダイレクトできる

リクエストヘッダを取得する

requestオブジェクトのgetHeaderNamesメソッドを使用

getHeaderNamesメソッド(requestオブジェクト)
Enumeration<String> getHeaderNames()
クライアントから送信されたヘッダ名の一覧を取得する

getHeaderNamesメソッドは、リクエストヘッダ名の集合をEnumerationオブジェクト(ある特定の対象の集合体を格納して取り出す)として返す
数値やtrue/falseのような基本データ型を含めあらゆるデータを格納できる
現在の値を示すポインタはnextElementメソッドで動かせる
ヘッダ値を数値、日付として取得したい場合それぞれgetIntHeader/getDateHeaderメソッドを使用することもできる

getHeader/getIntHeader/getDateHeaderメソッド(requestオブジェクト)
String getHeader(String name)
int getIntHeader(String name)
long getDateHeader(String name)
name:ヘッダ名
指定されたヘッダ名に対応する値をそれぞれ文字列/整数/日付として取得する

ただしgetIntHeader/getDateHeaderメソッドでは、ヘッダ値がそれぞれ対応するデータ型に変換できない場合エラーとなる

ヘッダ情報を取得するための専用メソッド

専用メソッドはヘッダ値をそれぞれの種類に応じた適切なデータ型で取得できるだけでなく、メソッド名に誤りがあった場合には明示的にエラーを発生する
統合開発環境を利用している場合、コード補完機能を利用できる
requestオブジェクトの役割として、リクエスト時のパス(URL)を取得することがある(取得したい部分に応じて複数のメソッドが用意されている)
スキーム名(プロトコル)やホスト名、ポート番号などを含めた完全なURLを取得したい場合はgetRequestURLメソッドを使用する

レスポンスヘッダを設定する(リダイレクト)

もともと指定されたHTTPメソッドがGETであるかPOSTであるかにかかわらずリダイレクト後の要求ではGETメソッドが使われる
リダイレクトは見かけ上一個のリクエスト処理だが、HTTPという観点で見ると2回のリクエストが自動的に行われている
responseオブジェクトは暗黙オブジェクトの一種でクライアントへの応答にかかわる機能を提供する

sendRedirectメソッド(responseオブジェクト)
void sendRedirect(String ur1) throws IOException
ur1:リダイレクト先のURL
指定されたURLに対してリダイレクト処理を行う

レスポンスヘッダを設定する(汎用的なヘッダの発行)

暗黙オブジェクトresponseにはレスポンスヘッダを発行するためのいくつかの専用メソッドがあり、これらを利用することでプロトコルレベルの操作を意識する必要がなくなり、コードをより直観的に記述できる
統合開発環境を利用している場合、コード補完機能を利用できる
専用メソッドでは対応できないようなヘッダを出力したい場合setHeader/setIntHeader/setDateHeaerメソッドを利用する
いずれも指定されたレスポンスヘッダを設定するためのメソッド

setXxxxxHeaderメソッド(responseオブジェクト)
void setHeader(String name ,String value)
void setIntHeader(String name ,int value)
void setDateHeader(String name ,long date)
name:ヘッダ名
value:ヘッダ値(文字列/数値)
date:ヘッダ値(197011日からの経過ミリ秒)
指定されたヘッダ名と値の組みをレスポンスヘッダに設定する

似たようなメソッドとしてaddXxxxxHeaderメソッドもある
指定されたヘッダがすでに存在する場合setXxxxxHeaderメソッドはその値を上書きするが、addXxxxxHeaderメソッドは新たに同名のヘッダを追加する

利用例

・指定された時間間隔でページを更新
・他のページにリダイレクトする
・ブラウザのキャッシュ機能を無効化

クッキー情報

クッキー(Cookie)とは、クライアント側に保存可能な小さなテキストのこと
一般的にサーバはクライアント上のファイルを勝手に読み書きできないが、クッキーは例外

クッキーの基本的な読み書き

Cookieコンストラクタ
Cookie(String name, String value)
    name:クッキー名
    value:クッキー値
    指定された名前と値の組み合わせでCookieオブジェクトを生成する

生成されたクッキーにはセッタメソッドで必要なパラメータを設定しておく

addCookieメソッド(responseオブジェクト)
void addCookie
(Cookie cok)
cok:クッキー
指定されたクッキーをクライアントに送信/記録する
getCookiesメソッド(requestオブジェクト)
Cookie[] getCookies()
クライアントに保存されたすべてのクッキーを取得する
クライアントに保存されたクッキーが存在しない場合nullを返す

クッキーで日本語を扱う

クッキーを日本語で扱うには、設定時に文字列のエンコードを、取得時にはデコード処理を行う必要がある
エンコード処理:URLEncoderクラスのencodeメソッド
デコード処理:URLDecodeクラスのdecodeメソッド

decodeメソッド(URLDecoderクラス)
static String decode(String s, String enc) throws UnsupportedEncodingException
s:任意の文字列
enc:文字コード
文字列を指定された文字コードでURLデコードする

クッキー教授の仕組み

JSPはレスポンスヘッダを介してクライアントにクッキーを送信している
クライアントではSet-Cookieヘッダを受け取るとこれを自分のマシン内にテキストファイルとして記録する
クッキーを保持したクライアントは該当サーバに対してリクエストするタイミングで、常にクッキーをサーバに送信する
サーバ側ではこれを適宜参照することでクッキーの値を復帰できる

クッキーの問題点

・データがクライアント側で保持される
・実データがネットワーク上を流れる

セッション情報

ユーザーがブラウザを開いている間だけ情報を維持したい場合セッションという仕組みを利用する
何日、何週間という単位で情報を保持する用途には不向きだが、アプリケーション内で情報を受け渡したい場合クッキーよりも手軽でセキュアに扱える

セッションの読み書き

getAttribute/setAttributeメソッド(sessionオブジェクト)
Object getAttribute(String name)
void setAttribute(String name, Object object)
name:キー名
object:値
セッション情報を取得/設定する。セッション情報のキー名はアプリケーション内で一意でなければならない

セッションを扱うことはサーバリソースをそれなりに消費するので必要な時だけ使うようにする

セッションの仕組み

クライアントを識別するために セッションID というものがある(クライアント単位で発行される)
セッション情報そのものはあくまでもサーバ側で管理されるものであり、クライアント/サーバ間でやり取りされるのはそのキーだけである
つまり
・データがサーバ側で管理される:クライアントによってデータが改ざん/削除される可能性は原則ない
・ネットワーク上を実データが流れない:データを盗聴される危険性が相対的に低下する

URLリライティング

セッションとは内部的にクッキーを使用した仕組み
URLリライティングを使うことでクッキーが利用できない環境でもセッションが使えるようになる

encodeURLメソッド(responseオブジェクト)
String encodeURL(String url)
url:URL 文字列
指定されたURLにセッションIDを付与する

セッションを利用する場合の注意点

セッションはサーバに負担をかけやすいため大きなデータを格納すべきではない
不要になったセッションはすみやかに確実に破棄する

セッションを明示的に破棄する
session.invalidate();

セッションの有効期限を設定する

session.setMaxInactiveInterval(600);

セッションの有効期限を設定する(設定ファイル)

アプリケーションルート配下の/WEB-INFフォルダにweb.xmlという名前でファイルを保存する