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

サーブレットの必要性

アプリケーションを構築する場合、ただ動けば良いのではなく、長期的に修正したり改造したりすることを考慮し、メンテナンスしやすいコードを書く必要がある
そのキーとなるのがサーブレットである

●暗黙オブジェクト

JSPによって自動的にインスタンス化されたオブジェクト

サーブレットの骨格

java.io,javax.servlet,javax.servlet.httpパッケージは必須

javax.servletおよびjavax.servlet.httpパッケージに属する4つのクラスはJSPでは自動的にインポートされるがサーブレットでは明示的にする必要がある

HttpServletクラスを継承すること

サーブレットがクライアントと通信を行うための最低限の手続きを定めた基本クラス

サーブレットの起点はdoXxxxxメソッド

サーブレットのエントリポイントとなるメソッド
エントリポイント とはクラスが呼び出されたタイミングで最初に実行されるメソッド
一般的によく使うのはdoGetかdoPostメソッド

doXxxxxメソッド
protected void doXxxxx(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
request:リクエスト情報
response:レスポンス情報
リクエストの実処理を定義する
XxxxxはGet,Post,Delete,Head,Options,Put,Traceのいずれか
@WebServletアノテーションを宣言する

サーブレットを呼び出すためのパス(URL)を宣言する
引数には呼び出しのパスを、アプリケーションルートからの絶対パスで指定

サーブレットをフォームから起動する

直接URLを指定してページを要求するとき、クライアントはサーバに対してGETという要求メソッドを送信している
その場合呼び出されたサーブレットはまずdoGetというメソッドを実行する

からページを要求する場合、クライアントはサーバに対してPOSTという要求メッセージを送信する
その場合呼び出されたサーブレットはdoPostメソッドを実行する
どのような場合にクライアントがGET要求あるいはPOST要求を発行するか

・doGetメソッドが呼び出されるケース
ブラウザから直接URLで指定した場合
ページ内のリンクから呼び出された場合
HTMLフォームの

タグでGET形式でページを要求した場合(
またはmethodオプションが無指定)
・doPostメソッドが呼び出されるケース
HTMLフォームの
タグでPOST形式でページを要求した場合(
)

JSP固有の要素に代わるもの

コンテンツタイプを指定する

@pageディレクティブのcontentType属性に相当する部分

response.setContentType("text/html;charset=UTF-8");

JSPページからでも呼び出せるが、コンテンツタイプが正しく認識されるためにはoutオブジェクトが生成される前にsetContentTypeメソッドをコールしなければならないので正しく認識されなくなる

暗黙オブジェクトを取得する

任意の文字列を出力するにはPrintWriterオブジェクトのprintメソッドまたはprintlnメソッドを呼びだす必要がある
暗黙オブジェクトに相当するが、サーブレットではそのまま使用することはできないので明示的にオブジェクトを生成する

スクリプトレットと宣言部

インスタンス変数:初めてサーブレットが呼び出されたとき初期化され、コンテナ起動間ずっと有効な変数
ローカル変数:処理の都度破棄される変数

シングルインスタンス・マルチスレッド

サーブレットの世界では、リソースの節約という観点からいったんインスタンス化したサーブレットクラスをそのままメモリ上に常駐し、同じサーブレットに対するリクエストは同じインスタンスで処理される(ひとつのインスタンスで複数のリクエストを処理する)

サーブレットのライフサイクル

initメソッドとdestroyメソッド

サーブレットの初回起動時、アンロード/更新時にだけ実行される
すべてのリクエストで共通して利用するようなリソースはinitメソッドで初期化しておくことでリソース読み込みのオーバーヘッドを軽減できる
初期化処理を必要になるまで行わないことを 遅延初期化 という

初期化パラメータを取得する

設定ファイルで定義可能な変数で、使用する環境によって変更する可能性の高い情報(パスや文字コードなど)を定義するために使用する

初期化パラメータをアノテーションで設定する
@アノテーション名(
    属性名 = 値,
    属性名 = 値,...
)
WebServletアノテーション(initParams属性)
@WebServlet(
    initParams = {
    @WebInitParam(name = "パラメータ名",value = "値"),
    @WebInitParam(name = "パラメータ名",value = "値"),...
    }
)

サーブレットのより高度な話題

ファイルのアップロード機能実装

・enctypeオプションを指定
・MultipartConfigアノテーションでアップロード設定する
・ファイルをアップロードする

getapartメソッド
Part getPart(String name)
throws OPException, IllegalStateException, ServletException
name:パラメータ名
指定されたパラメータ名に対応するファイルを取得する
Writeメソッド
void write(String fileName) throws IOException
fileName:保存先のパス
現在のファイルを指定されたパスに保存

・Partオブジェクトからファイル情報を取得する
・アップロードファイルの種類をチェック
・URLパターンのワイルドカード指定
すべてのリクエストを1つのサーブレットで受け取るサーブレットのことを フロントコントローラ という
・フロントコントローラを定義する
getPathInfoメソッドで取得できる部分を拡張パス情報とよぶ(クエリ情報に近い)
・コンテナ起動時にサーブレットを初期化する

アプリケーションフレームワーク

フレームワークとはアプリケーションを開発するときのテンプレートのようなもの
開発生産性の向上が見込める

JSP&サーブレットの連携

サーブレットの処理結果をJSPページで表示する
リクエスト属性

ひと連なりのリクエスト処理の中で保持可能な変数

setAttributeメソッド(HttpServletRequestインターフェース)
void setAttribute(String name, Object value)
name:属性名
value:変数
指定された変数をリクエスト属性に登録する
forwardメソッド(RequestDispatcherインターフェース)
void forward(ServletRequest request, HttpServletReaponse response) throws
ServletException, IOException
request:リクエスト情報
response:レスポンス情報
指定されたページにリクエスト処理を転送する
getRequestDispatcherメソッド(ServletContextインターフェース)
RequestDispatcher getRequestDispatcher(String path)
path:アプリケーションルート/で始まるパス
指定されたパスに処理を転送するためのRequestDispatcherオブジェクトを取得する

リダイレクト

いったんレスポンスをクライアントに返したうえで自動的にサーバにリクエストを発生させる仕組み
内部的にはサーバ/クライアント間で通信の行き来が2往復発生していることになる
2回目のリクエストはサーバ側で待ち行列の末尾に配置されるので遅延が発生することもある

フォワード

サーバ内で処理を異なるページ(クラス)に転送する
サーバ/クライアント間では1度しか処理が発生しない

リダイレクトとフォワード

フォワードのほうがリダイレクトより高いパフォーマンスが望める
・リクエスト情報を引き継げるのはフォワードのみ
フォワードを利用できるのはサーバ内部の転送においてのみ(http://~で表さなければならないURLにはリダイレクトを使用する必要がある)

リクエスト情報の参照(JSP)

サーブレットクラスでリクエスト属性が設定できたらJSPページから参照する

変数のスコープ

変数の有効範囲のこと

●JavaBeans

クラスをより汎用的に部品化できるようにちょっとしたルール付けをした結果できたクラスという感じ

JavaBeansが必要な理由

性質の異なるコードを一つにまとめるとコードの再利用を阻害することになる
本来のデータ処理機能とそのほかの入力データの処理、処理結果の引き渡し機能とをさらに分離する必要がある
このような設計のことを MVC(Model-View-Controller)モデル といいJSP&サーブレットアプリケーションを構築する際一般的に採用される
MVCモデルではJavaBeans具体的なビジネスモデル(Model)を記述し、JSPユーザインタフェース(View)を実装し、両者へのデータの引き継ぎ及び割り振りをサーブレットが制御する(Controller)というように役割を明確に分担する

JavaBeansクラスの条件

1.引数のないコンストラクタを持つこと
コンストラクタをはクラスがインスタンス化される際最初に呼び出される特別なメソッドでクラスと等しい名前をもつ
オブジェクトの初期化処理を記述するのが一般的
JavaBeansでは引数をもたせてならない
2.プロパティを参照/設定するためのアクセサメソッドを定義すること
JavaBeansに保持するインスタンス変数は原則的にprivate変数として定義しなければならない(外部クラスからはJB内部のインスタンス変数に直接アクセスできない)
代わりにsetXxxxx/getXxxxxという名前のメソッドを介して行えるようにしておく(アクセサメソッド)
アクセサメソッドによって外部から隠蔽(カプセル化)されたフィールドのことを プロパティ という

アクセサメソッド
public データ型 get<プロパティ名>() {
 return this.プライベート変数名;
}...参照用メソッド

public void set<プロパティ名>(データ型 引数){
 this.プライベート変数名 = 引数;
}...設定用メソッド

読み書きの制御が可能、値の参照/設定時に任意の処理を記述できるなどのメリットがある

3.Serializableインターフェースを実装すること
そのクラスがシリアル化可能であることを表す
シリアル化とは直列化という意味でオブジェクトからバイト列への変換のこと(逆を復元という)
データの共有を目的としたJavaBeansでは汎用的なデータ交換の仕組みを備えている必要がある

JSTLをダウンロードしたところ

http://jstl.java.net/download.html

教科書ではこれからダウンロードってなっていたのだけれど

行ってみたらなんかsorryってなっていたので調べることに。

 

よくわからぬままここから頂いたけど動作に問題はないので大丈夫だと思う

最新バージョンもあるみたいだけどとりあえず教科書に合わせてver1.2.1

・javax.servlet.jsp.jstl1.2.1.jar

・javax.servlet.jsp.jstl-api-1.2.1.jar

この二つをダウンロードした

https://mvnrepository.com/artifact/org.glassfish.web/javax.servlet.jsp.jstl/1.2.1

 

ダウンロード後はEclipseのプロジェクトのWEB-INF/libってとこにふたつとも置いて完了

MySQLの起動ができなくなった時と文字化けが起こったときすること

ターミナルで起動できないとき

-rw-r----- 1 _mysql admin(ここの権限を変える(これは変えた後のやつ) 71283 6 6 20:03 マシン名.local.err

sudo chown -R 名前:admin /usr/local/var/mysql/マシン名.local.err 

 

ググったり、何してもわからなかったらここを見る
ここにはエラーのログがかいてある
ここに書いてあるエラー内容をみて調べる

sudo vim /usr/local/var/mysql/マシン名.local.err

 

文字化けについて

 

 

参考にした記事

mysqldにつては「default-character-set=utf8」から「character-set-server=utf8」に変更されたらしいので注意が必要 *http://qiita.com/WizowozY/items/5d7224be92aa8364a42a から引用

 

qiita.com



 

環境設定やり直しを振り返る

 

つい最近EclipseMarsの設定をしたのにTomcatとの関係がうまくいかなくて今日すべてやり直しました。

 

だからこの前書いた記事はボツだね。

あ、でも自分の役には立ってるのだけど。今回も見直したし。

 

Eclipseの環境設定欄のserverランタイム設定するとこがでなくなったり

コマンドプロンプトからだとTomcatが起動できるのにEclipseからだとできなかったり

わけがわからなくなったから、もうEclipse新しいのダウンロードしちゃおうってなって

どうせならMac版のpleiadesAllinoneがでたみたいだからそれを使って

再び設定を試みた。

Allinone版だと日本語にする作業も省けるし

Tomcatも入ってるぽい(ぽいんだけど環境設定のとこにTomcatの欄はなくて、結局serverランタイムでは、この前ダウンロードして/Library/Tomcatに置いておいた8.0.44を使って設定した)

 

ランタイムの設定は前うまくいかなくてつまずいたとこだったから、とりあえず少し進んだのでした。

 

でもなんかTomうまく動いてくれない。

起動はしてくれる・・。

相談してみたら、この記事を読みながら設定してくださった。

 

 

www.javaroad.jp

 

プロジェクト作るとこからなんか違うことしちゃってたみたいで

新しいプロジェクトをこれにそって作ったらうまく動いてくれた。

 

ここ最近ずっと環境構築でつまずいていたから少し進んで本当によかった〜

自分で調べるのも大事だけど、何時間もそこでつまずくようならやり方を変えたほうがいいよと教えてもらった。

例えば今回だったら、一時間調べても解決できなかったらmarsでずっと頑張るんじゃなくて、一からインストールしなおすとかバージョンを変えてみるとか。

仕事をするようになったり、できるようになってきても、理由がわからんことでつまずくことはあるらしくて(時間がたつとわかることもある)、そういうときは抜け出すのにすごく苦しむって。

今回みたいにバージョン変えられたらいいけど、それできないこともたくさんあるだろうしね、大変。

 

Eclipse苦手になりそうだったけど(最初から好きではない)コマンド操作も結構使えたし今回は良い勉強になったかな!

まだ他の章でも環境設定ありそうだからまたつまずくだろうけどがんばろ〜。

 

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

JSTL

アクションタグ はJSPページからプログラム的な要素のほとんどを取り除き、ソースコードを簡略化する
アクションタグと式を組み合わせることでJavaに精通していない人でもJSPページを記述できるようになる
アクションタグを駆使したコーディングを行う場合、JSTLの導入が必要になる
自分で個別に用意したタグのことを カスタムタグ という
カスタムタグをライブラリ形式でまとめたものを タグライブラリ という
JSTLは特に標準的なカスタムタグを集めたもの
JSTLJava標準化組織であるJCPでJSRとして承認されたもので、近年はスクリプティング要素主体のJSPページ開発から、JSTLを使用した開発に主流がうつっている

・変数の出力をJSTLで表現する

@taglibディレクティブ
<%@ taglib prefix="カスタムタグの接頭辞" uri="タグライブラリ識別のURI" %>
JSPページで使用するタグライブラリを有効化する

・式言語(EL式)

指定された式の値をより簡単に出力できる

式言語
${任意の式}
指定された式の値を出力する

特徴
・与えらえた式を評価し出力することがすべて
・データ型の制約が緩い
・あいまいな式の記述が可能
Javaの知識がなくても記述できる

・Coreタグライブラリ

変数の設定/出力から条件分岐、繰り返し処理など、Javaの基本的な制御構文を代替するライブラリ
・スコープ変数を設定する(ある決められた範囲で有効な変数のこと)
 ・ページスコープ
 ・リクエストスコープ
 ・セッションスコープ
 ・アプリケーションスコープ
 などがある
 値はvalue属性または要素配下のテキストとして指定できる
 value属性と要素本体とはいずれか片方しか指定できない
・変数の値を出力する
・単純分岐を実装する
・多岐分岐を実装する
・繰り返し処理を行う
・Mapの内容を列挙する
・ステータス変数を利用する

・Databaseタグライブラリ

データベースへのデータ登録/更新/検索など基本的なデータベース連携の手段を提供する
java.sqlパッケージに相当する機能を提供するライブラリ
・Databaseタグライブラリでデータベースを検索する
・Databaseタグライブラリでデータを登録する

i18nタグライブラリ

i18nタグライブラリは、日付や数値、メッセージの整形などをロケール(地域情報)に応じて制御する手段を提供する
SimpleDateFormatやDecimalFormat,MessageFormatクラス,Localクラスを代替するライブラリ
・数値データの加工
・日付データの加工
・文字列を数値/日付データに変換
ロケール情報を設定
・国際化対応ページを作成する

・Functionタグライブラリ

文字列を加工するための機能を提供する
Stringクラスを代替する式言語ベースのライブラリ
複数の機能を適用したい場合には複数のタグ(関数)を入れ子に記述することもできる

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

データベース

後から検索・分析することを目的に、体系的に蓄積した情報群のこと

データベースサーバ

データベースに情報を確実に矛盾なく蓄積、更新し、必要な情報を大量のデータの中から高速に取り出すための手段を提供するソフトウェア

データベースの種類

・カード型データベース
一つの情報を一枚のカードとして扱う
・ネットワーク型データベース
関連するデータ同士が網状に関連付けられる
・リレーショナルデータベース
現在の主流
関連する一連のデータをテーブルに格納する

mysqlクライアント

MySQLにアクセスするにはMySQLに標準で付属しているコマンドラインツールであるmysqlクライアントを利用する

JDBC

データベースごとの仕様差を吸収し、Javaアプリケーションがデータベースに対してなんらかのアクセスを試みる際に一元的なインターフェースを提供するもの
コアはJavaSEのjava.sqlパッケージで提供されている
実際に各DBへの接続や操作を担うのは、個々のJDBCドライバである
DBによって別個に提供されているので必要に応じて適切なドライバをインストールする必要がある

データベース接続

JSPアプリケーションからDBを操作するには、DBに対して接続を確立しなければならない
接続をプール(保管)しておくために コネクションプーリング という仕組みを利用する
・いちいち接続を確立する必要がなくパフォーマンスがよい
・ユーザー数の増減に比較的強い
コネクションプーリングを管理する一連の手続きを規定するのが データソース の役割
設定はcontext.xmlに対して行う。アプリケーションルート配下の/META-
INFフォルダに保存する(要コンテナ再起動)
データソースの情報を定義するのは要素配下の要素である

データソースURL

データベース接続のための基本情報を表す

jdbc:subprotocol:subname

subprotocolにはJDBCドライバを識別するための文字列を指定する

データベース接続の基本

登録したデータソースを取得するにはInitialContextクラスのlookupメソッドを使用する
lookupメソッドの引数にはjava:comp/env/データソース名の形式で使用したいデータソースを指定する必要がある
戻り値はObjectクラスなので必ずDataSourceオブジェクトへの型キャストを行う必要が有る

データベース切断時注意

原則としてcloseメソッドはfinallyブロックで記述すること

SQLクエリの発行

DBに発行する一連の命令を管理するのはPreparedStatementオブジェクトの役割でConnectionオブジェクトdbからprepareStatementメソッドを呼び出すことで取得する

PrepareStatementメソッド(Connectionインターフェース)
PreparedStatement prepareStatement(String sql) throws SQLException
sql:発行するsql命令
指定されたSQL命令を実行するためのPreparedStatementオブジェクトを取得する
SQLの命令には?の形式でプレースホルダを含めることが可能
setXxxxxメソッド(PreparedStatementインターフェース)
void setXxxxx(int i,T value) throws SQLException
i:パラメータの番号(1スタート)
value:値(Tはデータ型がメソッドに応じて変動する意味)
プレースホルダ?に対して指定された値をセットする
Xxxxxの部分はBoolean,Byte,Date,Double,Float,Int,Long,Short,String,Timeなど

結果セット取得

SQLのSELECT命令によって、一つまたは複数のテーブルから取り出されたレコード群を保持するためにメモリ上に用意された仮想テーブルのこと
結果セットを読み込む場合、レコード単位で読み込む必要がある
現在読み込み可能なレコードを表す内部的な目印のことを レコードポインタ といい、それが示す現在行を カレントレコード という
結果セットから個々の行を取り出すことを フェッチする という

nextメソッド(ResultSetインターフェース)
boolean next() throws SQLException
レコードポインタを次のレコードに移動する
ポインタの移動に成功した場合はtrueを、そうでないならfalseを返す
getXxxxxメソッド(ResultSetインターフェース)
T getXxxxx(int i)
T getXxxxx(String name)
T:Boolean,Byte,Date,Double,Float,Int,Long,Short,String,Timeなど
i:インデックス番号
name:フィールド名
カレントコードから指定されたフィールドの値を取得する

トランザクション処理

分けることのできない複数の処理をグループ化したもの
処理を元に戻すことを ロールバック といい、トランザクションに属するすべての処理をなかったことにする
自動コミット はSQL命令を一つ発行するたびトランザクションを自動的に確定する機能

メタデータまたはメタ情報

データの構成を表すためのデータのこと

getTablesメソッド(DatebaseMetaDataインターフェース)
 ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern,
 String[] types) throws SQLException
 catalog:データベース名
 schemaPattern:スキーマ名
 tableNamePattern:テーブル名
 types:テーブルの種類
 指定されたテーブルのメタ情報を取得する
 テーブルの種類は文字列配列で指定可能
getColumnsメソッド(DatebaseMEtaDataインターフェース)
 ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
 catalog:データベース名
 schemaPattern:スキーマ名
 tableNamePattern:テーブル名
 columnNamePattern:フィールド名
 指定されたテーブルに含まれるフィールドのメタ情報を取得する
getMetaDataメソッド(ResultSetインターフェース)
 ResultSetMataDate getMetaData() throws SQLException
 結果セットの構成情報をResultSetMetaDataオブジェクトとして返す

独習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という名前でファイルを保存する