連載
» 2003年07月11日 00時00分 公開

基礎から学ぶサーブレット/JSP(7):クラスライブラリを攻略「基本クラス編」 (1/3)

[山田祥寛,@IT]

 Javaには、クラスライブラリが用意されています。暗黙オブジェクトを学ぶことが、サーブレット/JSP(サーバサイドJava)の基本を学ぶということであるならば、クラスライブラリを学ぶということはJavaの基本を学ぶということでもあるのです。

 クラスライブラリのすべてをこの場で取り上げることは(当然)できませんし、そもそもクラスライブラリには、サーブレット/JSPに縁の薄いSwingのようなGUI系のクラスライブラリも含まれます。

 今回から3回に分けて、その膨大なライブラリの中でも、特に重要な――サーブレット/JSPとの関係が強いクラスについて紹介することにしましょう。以下は、本連載で紹介するクラスです。

表1 紹介するクラス(赤い文字が今回紹介するクラス)
パッケージ名 クラス名 概要
java.awt Graphics すべてのグラフィックコンテキストの抽象基底クラス
java.awt.image BufferedImage イメージデータを保持
java.io BufferedReader 文字型入力ストリームから効率よくテキストを読み取る手段を提供
BufferedWriter 文字型出力ストリームに効率よくテキストを書き込む手段を提供
File ファイルシステム情報を保持
FileReader テキストファイルからの読み取り手段を提供
java.lang ラッパクラス 基本データ型の操作に利用(Integer、Longなど)
Math 指数関数、対数関数、三角関数などの基本的な演算処理
Package パッケージ名、仕様、バージョンに関する情報を保持
String 文字列の加工・制御手段を提供する
StringBuffer 可変長文字列の操作手段を提供する
System システム全般の制御、情報の取得手段を提供
java.sql CallableStatement ストアドプロシージャを実行
Connection データベースとの接続を管理
DatabaseMetaData データベースの構成情報を保持
PreparedStatement 準備済みSQL命令を実行
ResultSet データベースから抽出した結果セットを操作
ResultSetMetaData 結果セットの構成情報を保持
Statement 静的なSQL命令を実行
DriverManager JDBCドライバを管理
java.text DecimalFormat 10進数を整形する手段を提供
SimpleDateFormat 日付型データを整形する手段を提供
java.util Calendar 標準的なカレンダーを提供
Date 日付情報を保持、また操作する手段を提供
HashMap 連想配列を実装
Locale ロケール(地域)情報を管理
ResourceBundle リソース(プロパティ)ファイルの参照手段を提供
StringTokenizer 文字列をトークンに分解
java.util.regex Matcher 正規表現マッチングを制御する
Pattern コンパイル済みの正規表現パターンを保持する
java.util.zip ZipEntry Zipエントリを表現
ZipOutputStream Zip形式で書き込みを行うための出力ストリーム

入力文字列をHTMLエンコードする―String/StringBufferクラス(1)―

 最初のサンプルでは、StringクラスとStringBufferクラスを用いて、HTMLエスケープメソッドhtmlEscapeを作成してみます。

 ブラウザ上では、「<」や「>」「&」のような文字をそのまま表示することはできません。このような予約文字を正しく表示するには、あらかじめ「&lt;」「&gt;」「&amp;」のようにエスケープ表現に変換しておく必要があります。

リスト1 htmlEscape.jsp
<%@ page contentType="text/html;charset=Shift_JIS" %>
<%!
private String htmlEscape(String strVar){
  StringBuffer strEsc=new StringBuffer();
  for(int i=0;i<strVar.length();i++){
    switch(strVar.charAt(i)){
      case '<' :
        strEsc.append("<");
        break;
      case '>' :
        strEsc.append(">");
        break;
      case '&' :
        strEsc.append("&");
        break;
      default :
        strEsc.append(strVar.charAt(i));
        break;
    }
  }
  return strEsc.toString();
}
%>
<%=this.htmlEscape("<JSP&Servlet Basic>")%>
画面1 「<」「>」のような文字を正しく表示。HTMLのソースを見ると、「&lt;JSP&amp;Servlet Basic&gt;」の文字列を確認することができる 画面1 「<」「>」のような文字を正しく表示。HTMLのソースを見ると、「&lt;JSP&amp;Servlet Basic&gt;」の文字列を確認することができる

ロジックの概要

 ユーザー定義メソッドhtmlEscapeは、引数として渡された文字列strVarを1文字ずつ読み込み(String#charAtメソッド)、読み込み文字が「<」や「>」「&」であった場合にはそれぞれ「&lt;」「&gt;」「&amp;」に変換し、それ以外の文字の場合にはそのまま、StringBufferオブジェクトobjSbに追記します(StringBuffer#appendメソッド)。文字列中のすべての文字を走査した後、戻り値として、StringBufferオブジェクトの内容を文字列に変換したもの(toStringメソッド)を返します。

StringクラスとStringBufferクラスとの違い

 上記の例では、文字列連結にStringクラスと「+」演算子を使用せず、StringBuffer#appendメソッドを使用して文字(列)を連結していきました。

 なぜ、

strEsc+="&lt;";

のようにしないのでしょう。

 これは、Stringクラスが本質的には「固定長の文字列」を表現するものであるからです。つまり、「+」演算子によって文字列を連結するとは、「連結される前の文字列」と「連結される文字列」と「連結した結果できた文字列」と、合計3つのStringクラスを内部的に生成していることを意味します。これはオブジェクト生成のオーバーヘッドをかんがみれば、あまりに無駄の多い処理でもあります。

 そこで、JSP(Java)の世界では、幾たびにもわたる文字列連結に際しては、StringBufferクラスを利用するのが一般的です。StringBufferクラスは「可変長の文字列」を表現することができ、あらかじめ一定のバッファを用意しています。つまり、文字列連結に際しても、バッファの後方に文字を追加していくだけで、新たなインスタンス(オブジェクト)は生成されないというわけです。

Stringクラスは固定長文字列、StringBufferクラスは可変長文字列を表現します。繰り返しの文字列連結にはStringBufferクラスを使用することで、パフォーマンスを向上させることができます。


リクエストパラメータの文字コードを変換する―String/StringBufferクラス(2)―

 JSP 1.2&サーブレット2.3(Tomcatならば4.x)の環境ならば、リクエストデータの文字コード設定にはHttpServletRequest#setCharacterEncodingメソッドを使用することができます。

 しかし、それ以前の環境でリクエストデータのコード変換を行う場合には、どのようにしたらよいのでしょう(少なくともそのままではフォームなどから日本語データを受け取ることができません)。

 ここではユーザー定義メソッドencodeを独自に作成し、リクエストデータを自前でエンコーディングしてみることにします。

リスト2 encode.jsp
<%@ page contentType="text/html;charset=Shift_JIS" %>
<%!
private String encode(String strVal) throws UnsupportedEncodingException{
  if(strVal==null){
    return (null);
  }else{
    return (new String(strVal.getBytes("8859_1"),"JISAutoDetect"));
  }
}
%>
<%=this.encode(request.getParameter("name"))%>

ロジックの概要

 ユーザー定義メソッドencodeは、リクエストデータとして受け取った文字列をgetBytesメソッドでいったんバイト配列(文字ではないbyte型数値の配列)に変換し、あらためてデコードすることで正しく文字コードの変換を行うものとします。

 “JISAutoDetect”は「自動変換」の意味を表しますが、もしもリクエストデータの文字化けが改善されない場合には、“Shift_JIS”や“EUC-JP”など、直接の文字コード名を指定してみてください。

Stringクラスのそのほかのメソッド

 サンプル中に登場したcharAtやgetBytesメソッドは、数あるStringクラスのメソッドのごく一部にすぎません。ここでは、そのほかによく使用される主なメソッドについて簡単に紹介しておくことにします。

表2 Stringクラスのそのほかのメソッド
メソッド 概要
compareTo(String anotherString) 文字列を辞書的に比較(元の文字列が大きい場合には正数、小さい場合には負数、等しい場合には0)

compareToIgnoreCase(String str)

文字列を辞書的に比較(大文字小文字を区別しない)

concat(String str) 文字列strを現在の文字列に連結
endsWith(String suffix) 文字列が接尾辞suffixで終わるかどうか(true|false)
equals(Object anObject) 文字列が指定された文字列anObjectと等しいかどうか
indexOf(String str[,int fromIndex]) 文字列中で指定文字strが最初に登場するインデックス位置。fromIndexが指定された場合には、そのインデックス値から走査を開始
lastIndexOf(String str, int fromIndex) 文字列中で指定文字strが最後に登場するインデックス位置。fromIndexが指定された場合には、そのインデックス値から走査を開始、 length() 文字列の長さを返す
replace(char oldChar, char newChar) 文字列中の文字oldCharをnewCharに置き換え
replaceAll(String regex, String replacement) 正規表現パターンregexに合致するすべての部分文字列を、指定された文字列replacementで置き換え
replaceFirst(String regex, String replacement) 正規表現パターンregexに合致する最初の部分文字列を、指定された文字列replacementで置き換え
split(String regex[, int limit]) 正規表現パターンregexに合致する個所で文字列を分割する。ただし、limitが指定された場合にはその回数分だけ分割する
startsWith(String prefix) 文字列が接頭辞prefixで始まるかどうか(true|false)
substring(int beginIndex, int endIndex) beginIndex+1文字目〜endIndex文字目までの部分文字列を抽出

toLowerCase() 小文字に変換
toUpperCase() 大文字に変換
trim() 前後の空白を削除

JSP 1.1&サーブレット2.2以前(Tomcatならば3.x)の環境ではHttpServletRequest#setCharacterEncodingメソッドは使えません。リクエストデータに2バイト文字が含まれている場合には自前のコード変換関数を定義する必要があります。


       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。