Servlet/JSP: Input Parameter
入力パラメータの取得
HTMLではformタグで入力を扱います。
formタグの属性は以下の通りです。
- action="URI" ... 送信先プログラムのURI
- method="HTTPメソッド" ... 送信の際の転送方法(HTTPメソッド)
- enctype="MIMEタイプ" ... 送信の際のデータ形式(MIMEタイプ)
- accept-charset="文字セット" ... CGIプログラム等のデータの受け側で、
受付可能な文字セット
- accept="MIMEタイプ"... CGIプログラム等のデータの受け側で、
処理可能なMIMEタイプ
- name="名前" ... スクリプト言語などから参照できるように
- target="フレーム名" ... フォーム送信の結果を表示するフレーム、またはウィンドウの名前
<form>〜</form>の間に
input, select, textareaなどのタグを
置くことでいろいろな形式で入力することができます。
[ファイル配置]
${CATALINA_HOME}/webapps/basic/input/echo.jsp
${CATALINA_HOME}/webapps/basic/input/echo.jsp |
<%@page contentType="text/html; charset=utf-8" %>
<html>
<head>
<title>Echo Servlet</title>
</head>
<body>
<h2>EchoServletの入力</h2>
<form action="../input/EchoServlet">
<input type="text" name="message">
<input type="submit">
</form>
</body>
</html>
|
[ブラウザでアクセスするURL]
http://localhost:8080/basic/input/echo.jsp
ページのソースの表示
[ファイル配置]
${CATALINA_HOME}/webapps/basic/WEB-INF/src/input/EchoServlet.java
${CATALINA_HOME}/webapps/basic/WEB-INF/src/input/EchoServlet.java |
package input;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
@WebServlet(name="input.EchoServlet",urlPatterns={"/input/EchoServlet"})
public class EchoServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String msg = request.getParameter("message");
response.setContentType("text/plain; charset=utf-8");
PrintWriter out= response.getWriter();
out.println("mesasge=" + msg);
}
}
|
EchoServlet.javaのコンパイル |
$ cd u:/Users/nitta/Documents/tomcat8/webapps/basic/WEB-INF
$ mkdir classes ← WEB-INF/classesは自動生成されないので無ければ作る
$ javac src/input/EchoServlet.java -d classes -sourcepath src
|
サーバへのデータの送り方(Getの場合)
http://localhost:8080/basic/input/EchoServlet?message=goodmorning
にアクセスをしてみましょう。
ただしくEchoServletで処理されてmessage="与えたデータ"が表示されると思います。
Getの場合は、サーバに送るべき文字列を
?属性=値&属性=値&...属性=値
という形式でパスの最後に付加して送っています。
このときに、データは次の「URLエンコード」とよばれる方法で
符号化されます。
URLエンコード
- 1バイトの英文字(A-Z, a-z, 0-9)と一部の記号(*-.@_)はそのまま
- 半角スペースは"+"に変換
- その他の文字は文字コードを2桁の16進数で表して、前に"%"をつける
受け取ったサーバの側では、URLエンコードされた文字列をデコードします。
このときに、エンコードと異なるcharactersetを想定してデコードを行うと
文字化けをしてしまいます。
上の例では、echo.jspの中で utf-8 を指定しているので
入力文字列はクライアント側では utf-8 というcharacterset
で表現されています。
これがURLエンコードされてサーバに送られてきますが、
サーバ側では送られてきたデータをデコードして、自分が内部表現として
使うcharactersetへと変換しなくてはいけません。
このときに元のデータのcharactersetが utf-8 であることを
知らなければ、間違ったcharactersetを想定して変換してしまい
(たとえば元の文字列がEUC-JPであると勘違いをして変換したら)
文字化けをしてしまうことになるわけです。
(注意) 手元のPCの日本語環境や使用しているブラウザ、サーバ側のtomcatのバージョンの組み合わせによっては、文字化けしない場合もあります。
日本語の入力
ServletRequest#setCharacterEncoding()メソッドは、
リクエスト(入力)のcharactersetを指定するメソッドです。
メソッドの引数としてcharactersetを指定します。
このメソッドでcharactersetを指定しない場合の
初期値は "ISO8859-1" なので、漢字を使うと文字化けしたわけです。
setCharacterEncoding()メソッドはgetParameter()メソッドよりも前に
呼び出す必要があることに注意をして下さい。
[ファイル配置]
${CATALINA_HOME}/webapps/basic/input/echo2.jsp
echo.jspからecho2.jspへの書き換え |
*** basic/input/echo.jsp Thu Jul 28 13:26:00 2011
--- basic/input/echo2.jsp Thu Jul 28 14:47:38 2011
***************
*** 6,12 ****
<body>
<h2>EchoServletの入力</h2>
! <form action="../input/EchoServlet">
<input type="text" name="message">
<input type="submit">
</form>
--- 6,12 ----
<body>
<h2>EchoServletの入力</h2>
! <form action="../input/EchoServlet2">
<input type="text" name="message">
<input type="submit">
</form>
|
[ファイル配置]
${CATALINA_HOME}/webapps/basic/WEB-INF/src/input/EchoServlet2.java
EchoServlet2.javaからEchoServlet2.javaへの書き換え |
*** basic/WEB-INF/src/input/EchoServlet.java Thu Jul 28 13:19:45 2011
--- basic/WEB-INF/src/input/EchoServlet2.java Thu Jul 28 14:22:14 2011
***************
*** 5,15 ****
import javax.servlet.http.*;
import javax.servlet.annotation.*;
! @WebServlet(name="input.EchoServlet",urlPatterns={"/input/EchoServlet"})
! public class EchoServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String msg = request.getParameter("message");
response.setContentType("text/plain; charset=utf-8");
PrintWriter out= response.getWriter();
--- 5,16 ----
import javax.servlet.http.*;
import javax.servlet.annotation.*;
! @WebServlet(name="input.EchoServlet2",urlPatterns={"/input/EchoServlet2"})
! public class EchoServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
+ request.setCharacterEncoding("utf-8");
String msg = request.getParameter("message");
response.setContentType("text/plain; charset=utf-8");
PrintWriter out= response.getWriter();
|
EchoServlet2.javaのコンパイル |
$ cd C:/User/nitta/Documents/tomcat8/webapps/basic/WEB-INF
$ javac src/input/EchoServlet2.java -d classes -sourcepath src
|
[ブラウザでアクセスするURL]
http://localhost:8080/basic/input/echo2.jsp
Tomcat5以降では
「GETで送られきたURL文字列のデコードには必ずISO8859-1が使われて
setCharacterEncoding()の呼び出しによる設定を無視する」
ようになりました。
POSTで送られてきた文字列は昔のバージョンのように
setCharacterEncodingの影響を受けますが。
setCharacterEncoding()が効力を持つようにserver.xmlを編集して、
tomcatを再起動して下さい。
[ファイル配置]
${CATALINA_HOME}/conf/server.xml
server.xmlの書き換え |
*** servlet/server.xml.org Mon Sep 15 18:21:53 2014
--- servlet/server.xml Mon Sep 15 18:21:53 2014
***************
*** 67,73 ****
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
! redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
--- 67,73 ----
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
! redirectPort="8443" useBodyEncodingForURI="true" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
|
PostとGet
上記のURLエンコードによる文字化けはGetでデータを送る場合にだけ起こります。
Postのときは、送るべきデータをURLに含めて送信することはしないからです。
HTTPプロトコルで、
WWWクライアントがWWWサーバに送る要求(リクエスト)には次の種類があります。
通常のサーブレットであればdoGet()とdoPost()だけを実装すればよいでしょう。
リクエストメソッド | サーブレット側のメソッド | 説明 |
GET | doGet() | コンテンツを取得する |
POST | doPost() | データを送信する。 |
HEAD | doHead() | コンテンツのヘッダ部を取得する。 |
PUT | doPut() | コンテンツを作成、更新する。 |
DELETE | doDelete() | コンテンツを削除する。 |
OPTIONS | doOptions() | 利用可能なオプションの一覧を得る。 |
TRACE | doTrace() | ループバックを起動する。 |
POSTメソッドが送られるのは、
「form文のmethod属性として"POST"が指定された」
場合だけです。
GETメソッドが送られるのは、
「ブラウザのアドレスバーに直接URLを打ち込んだ」場合、
「ブラウザ上リンクをクリックした場合」、
「form文のmethod属性として"GET"が指定された」場合、
「form文のmethod属性の指定が省略された」場合などです。
つまり、かなり多くの場合においてGETメソッドが送られることになります。