Servlet/JSP: Input Parameter


入力パラメータの取得

HTMLではformタグで入力を扱います。 formタグの属性は以下の通りです。

<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エンコード

受け取ったサーバの側では、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()だけを実装すればよいでしょう。

リクエストメソッドサーブレット側のメソッド説明
GETdoGet()コンテンツを取得する
POSTdoPost()データを送信する。
HEADdoHead()コンテンツのヘッダ部を取得する。
PUTdoPut()コンテンツを作成、更新する。
DELETEdoDelete()コンテンツを削除する。
OPTIONSdoOptions()利用可能なオプションの一覧を得る。
TRACEdoTrace()ループバックを起動する。

POSTメソッドが送られるのは、 「form文のmethod属性として"POST"が指定された」 場合だけです。

GETメソッドが送られるのは、 「ブラウザのアドレスバーに直接URLを打ち込んだ」場合、 「ブラウザ上リンクをクリックした場合」、 「form文のmethod属性として"GET"が指定された」場合、 「form文のmethod属性の指定が省略された」場合などです。

つまり、かなり多くの場合においてGETメソッドが送られることになります。