GO BACK

JSP教室 その3


「JSPとサーブレット」


■JSPで作られるもの

 前回、JSPのファイル内にJavaのコードを埋め込んで動かすことに成功したけれど、しかしこのJSPというのは、なんだって「ただのテキ ストファイルに書いたJavaのプログラム」を動かせるようになっているのだろう? そう思っている人も多いことと思います。ここで、JSPがやっている ことをちょっと見てみましょう。

 Tomcatがインストールされているフォルダの中に「work」というフォルダがあります。その中を、ちょっと覗いてみましょう。以下のよ うな、奥深いフォルダ階層の中に、それはあります。

Tomcat フォルダ/work/Catalina/localhost/JSP/org/apache/jsp/


 ここに、「test1_jsp.java」「test1_jsp.class」という2つのファイルが見つかるはずです。これは一体、何か? 実をいえ ば、これが前回作成したtest1.jspというJSPからTomcatによって生成されたJavaのソースコードとそのクラスなのです。

 このtest1_jsp.javaをテキストエディタで覗いてみましょう。こんなものがずらずら〜っと出てきて驚くはずです。

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
import java.text.*;

public final class test1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {

private static java.util.Vector _jspx_dependants;

public java.util.List getDependants() {
return _jspx_dependants;
}

public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {

JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;


try {
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html; charset=Shift_JIS");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;

out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<title>Test JSP</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\r\n");
out.write("\r\n");

GregorianCalendar gr = new GregorianCalendar();
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
String str = df.format(gr.getTime());
out.println("<h2>" + str + "</h2>");

out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write("\r\n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
}
}
}


 なんだかずいぶんとややこしそうに見えますが、余計な部分は省略して、色分けしてある部分だけをよく見て下さい。両者を比べれば、JSPに書 いたスクリプトとこのソースコードとは、以下のように対応していることがわかってくるはずです。

 つまり、JSPというのは、「そのファイル内のタグを解析して、それをJavaの文に翻訳するもの」だったわけです。もう少し詳しくいうな ら、JSPは以下のような動作をしています。

  1. JSPが呼び出されると、まずそのJSPファイルから生成されたクラスがないかをチェックする。
  2. ない場合、あるいは既にあるクラスファイルよりJSPファイルが更新されている場合は、以下の処理を行なう。
    1. JSPファイルのタグを解析し、それを元にJavaのソースコードファイルを作成する。
    2. 作成されたソースコードをコンパイルしクラスファイルを生成する。
  3. JSPファイルから生成されたクラスファイルを読み込み、サーブレットとして実行する。

 生成されたソースコードは、「サーブレット」と呼ばれる Javaのプログラムです。サーブレットは、サーバサイドのアプレットといったものです。アプレットがWebブラウザからロードされその中で実行されるよ うに、サーブレットはサーバからロードされその中で実行されます。

 つまり、Javaの技術として考えれば、実は「JSPというものはない」のです。あるのは、サーブレットという技術だけ。JSPと呼ばれるも のは、「テキストファイルに書かれたタグを解析してサーブレットを自動生成するツールをサーバにつけたもの」だったわけですね。

※ 「JSPはない」というなら、なんでない機能が動いてんだ?とか思われちゃうかも知れませんね。つまり、Java自身に「JSPのスクリプトを実行する」 という機能があるわけじゃない、ってことです。Javaが実行しているのは、あくまでサーブレットなんですね。


■リクエストにお応えして!

 この「JSP = 実はサーブレット」ということがわかってくると、例えば「out」というオブジェクトの意味がわかってきます。先ほどのソースコードを見ていくと、こうい う処理がされていることがわかるでしょう。
JspWriter out = null;
out = pageContext.getOut();
 ここで使われている「JspWriter」というのは、J2EEのjavax.servlet.jspパッケージに用意されているクラスで、平たくいえ ば「Jsp用のOutputStream」す。このoutを、JSPの中で指定していたのですね。<% %>タグで記述したコードは、そのままサーブレットのソースコードの中に組み込まれます。従って、サーブレットクラスで利用できるフィールドやメ ソッドは、そのまま記述してもコンパイルが通るわけです。

 さて、基本的な仕組みがわかったところで、もうちょっとJSPっぽい機能の話もしておきましょう。前回は「結果を出力する」ことをやりましたから、今度 は次の段階として「入力を受け取る」という方法について説明します。

 Webサイトで「ユーザからの入力を受け取る」ための方法としては、<form>タグを使ってテキストなどをPOSTする、というやり方が とられますね。JSPでもこれは同じです。JSPの場合、以下のような形で処理をします。


 つまり、POSTする側から送られた情報を受け取ったJSP側のrequestを使って取り出してやればいい、というわけです。――では、簡単な例を 作ってみましょう。まず、POSTするフォームを作成します。これは新たにHTMLファイルを作成してもいいですし、面倒ならtest1.jspを書き換 えて使ってもいいでしょう。

<html>
<head>
<title>Test JSP</title>
</head>
<body>
<h4>あなたのお名前を教えて!</h4>
<form action="answer.jsp" method="POST">
<input type="text" name="text1" size=40>
<input type="submit" value="Click">
</form>
</body>
</html>


 よくあるPOSTでテキストを送信するフォームですね。text1というテキスト入力フィールドと「Click」というsubmitボタンがあるだけの ものです。――では、受け取る側のJSPを作成しましょう。これは「answer.jsp」というファイル名にしてください。

<%@ page 
contentType="text/html; charset=Shift_JIS"
pageEncoding="Shift_JIS" %>
<html>
<head>
<title>入力ありがとう</title>
</head>
<body>
<%
request.setCharacterEncoding("Shift_JIS");
String str = request.getParameter("text1");
out.println("<h3>こんにちは、" + str + "さん!</h3>");
%>
</body>
</html>


 作成したら、2つのファイルを例の「myJSP」フォルダの中に入れておきましょう。そして、フォーム側のファイルにWebブラウザでアクセスをしま す。現れたフォームでテキストフィールドに名前を入力して「Click」ボタンを押せば、渡された名前のテキストを使って返事が表示されます。



 ここで使われているrequestインスタンスでは、以下の2つの処理を行なっています。

request.setCharacterEncoding("Shift_JIS");

 まず、文字のエンコーディング方法をシフトJISにしています。これは、お約束ということで。これを忘れると、送信された日本語テキストをうまくエン コードできません。

String str = request.getParameter("text1");

 そして、これが受け取った情報から「text1」テキスト入力フィールドのテキストを取り出している部分です。getParameterで引数に inputの名前を指定することで、そのinputのvalueを得ることができます。

 後は、得られたテキストを元に表示をout.printlnしていくだけです。――これで、「情報の入力」「結果の出力」ができるようになりました。 ちょっとしたCGI程度のものならJSPで十分作れるようになりますね。


※フォー ム送信テキストが文字化けする!
実際に試してみると、フォームから送信されたテキストがなぜか文字化けして表示されてしまう現象が発生した人もいるかも知れません。 <@ page>でcontentTypeを設定したのに、request.setCharacterEncodingも用意したのに、どうしても文字化 けがなおらない・・という人。
 実は、Tomcatはver.5.xあたりから「フォームからGETで送信された内容に関しては setCharacterEncodingによるエンコーディングの指定を適用しない」というような形に仕様が変更されています。このため、テキストが文 字化けしてしまうのですね。
 この問題を解消するためには、以下の手順で設定を変更します。

  1. Tomcatのconfディレクトリ内にあるserver.xmlをテキストエディタなどで開きます。
  2. <Connector・・・>というタグを検索します。
  3. このタグ内に以下のような属性を追記します。
	useBodyEncodingForURI="true"
以上で、TomcatをリスタートすればフォームからGETしたテ キストの文字化けが怒らなくなるはずです。


GO NEXT


GO HOME