第5章 リクエスト情報の取得(HttpServletRequest)
リクエスト情報の取得(HttpServletRequest)
homepage
# **リクエスト情報の取得(HttpServletRequest)** *** ## **1.HttpServletRequestインターフェース** サーブレットに対して「GET」メソッドでリクエストがあった場合に呼び出される「doGet」メソッドを見てください。 ``` import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } } ``` 2つの引数が「doGet」メソッドには渡されてきます。その中の1つが「HttpServletRequest」インターフェースのオブジェクトです。<br> クライアントからサーブレットに送られてくるリクエストに関する情報はこのオブジェクトに含まれています。そこでまずは「HttpServletRequest」インターフェースについて見ていきます。 <br> ## **2.HttpServletRequestインターフェースの定義とメソッド** 「**HttpServletRequest**」インターフェースは次のように定義されています。 ``` javax.servlet.http Interface HttpServletRequest public interface HttpServletRequest extends ServletRequest ``` 親インターフェースである「ServletRequest」インタフェースを継承しています。<br> 「HttpServletRequest」インターフェースと「ServletRequest」インタフェースでは多くのメソッドが用意されています。 <br> ## **3.リクエストパラメータの取得(getParameter)** 「HttpServletRequest」インターフェースのオブジェクトからは色々な情報が取り出せますが、一番利用頻度が高いリクエストパラメータの取得方法から見ていきます。リクエストパラメータとはクライアント側のフォームから送られてきたデータです。<br> リクエストパラメータは「名前」と「値」のペアで送られてきます。GETメソッドとPOSTメソッドの両方で送られてくる可能性がありますが、サーブレットではどちらのHTTPメソッドで送られてきたかを意識せずに処理することが可能です。 <br> ## **4.getParameterメソッドとgetParameterValuesメソッド** リクエストパラメータを取得するには「HttpServletRequest」インターフェースの親インターフェースである「ServletRequest」インタフェースで定義されている「getParameter」メソッドを使います。 **getParameter** ``` public java.lang.String getParameter(java.lang.String name) ``` リクエストパラメータの「名前」を引数に指定すると「値」を取得することが出来ます。例えば次のように使います。 ``` public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String val = request.getParameter("name"); } } ``` また1つの「名前」に対して複数の「値」が送られてくるとがあります。その場合「getParameter」メソッドでは「値」の中の最初のものだけを取得することができます。全ての「値」を取得するには「getParameterValues」メソッドを使います。 **getParameterValues** ``` public java.lang.String[] getParameterValues(java.lang.String name) ``` #### **例** **RequestSample1.java** ``` package hello; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RequestSample1") public class RequestSample1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String name = request.getParameter("name"); int old; String tmp = request.getParameter("old"); if (tmp == null || tmp.length() == 0) { old = -1; } else { try { old = Integer.parseInt(tmp); } catch (NumberFormatException e) { old = -1; } } String food[] = request.getParameterValues("food"); StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<p>お名前は "); sb.append(name); sb.append(" です</p>"); sb.append("<p>年齢は "); if (old == -1) { sb.append("未設定です</p>"); } else { sb.append(old); sb.append(" です</p>"); } sb.append("<p>好きな果物は "); if (food != null) { for (int i = 0; i < food.length; i++) { sb.append(food[i]); sb.append(" "); } sb.append(" です</p>"); } else { sb.append("選択されていません</p>"); } sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } } ``` **RequestSample1.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <p>アンケート調査です</p> <form action="../RequestSample1" method="get"> <table> <tr> <td>氏名</td> <td><input type="text" size="20" value="" name="name"></td> </tr> <tr> <td>年齢</td> <td><input type="text" size="5" value="" name="old"></td> </tr> <tr> <td>好きな果物</td> <td><select name="food" size="3" multiple> <option value="apple">りんご</option> <option value="melon">メロン</option> <option value="grape">ぶどう</option> </select></td> </tr> </table> <input type="submit" name="button1" value="送信"> </form> </body> </html> ``` #### **実行結果** <!--graph5-1.png --> <img src="https://i.loli.net/2019/06/27/5d1477aa8401f41106.png" width="40%" /> <br> ## **5.日本語パラメータの対応(getBytes)--文字列をバイト列に戻す** 「getParameter」メソッドなどで取得した文字列の値は、先ほど書いたとおりクライアントから送られてきたバイト列を文字コード「ISO-8859-1」で文字列に変換したものです。そこで文字列をまず元のバイト列に戻します。それには「String」クラスで用意されている「getBytes」メソッドを使います。 **getBytes** ``` public byte[] getBytes(String charsetName) throws UnsupportedEncodingException ``` 文字コード「ISO-8859-1」を使って文字列にしたものを元に戻したいので引数には「ISO-8859-1」を指定して文字列をバイト列に変換します。例えば次のように使います。 ``` public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String val = request.getParameter("name"); try { byte[] byteData = val.getBytes("ISO-8859-1"); }catch(UnsupportedEncodingException e){ System.out.println(e); } } } ``` **バイト列から文字列を作成する**<br> 次にバイト列を文字列に変換します。今度は正しい文字コードを使って変換します。Stringクラスのコンストラクタの1つに、バイト列と文字コードから文字列を作成するコンストラクタが用意されているためそれを利用します。 **String** ``` public String(byte[] bytes, String charsetName) throws UnsupportedEncodingException ``` ここで指定する文字コードは、元々のデータを送ってきたフォームがURLエンコードに使った文字コードです。基本的にブラウザはフォームが含まれるHTMLページの文字コードを使ってエンコードを行います。例えば文字コードとして「UTF-8」を指定する場合には次のように記述します。 ``` public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String val = request.getParameter("name"); try { byte[] byteData = val.getBytes("ISO-8859-1"); val = new String(byteData, "UTF-8"); }catch(UnsupportedEncodingException e){ System.out.println(e); } } } ``` #### **例** **RequestSample2.java** ``` package hello; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RequestSample2") public class RequestSample2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String tmp; String name = ""; tmp = request.getParameter("name"); if (tmp == null || tmp.length() == 0) { name = "未設定です"; } else { name = decodeString(tmp); } int old; tmp = request.getParameter("old"); if (tmp == null || tmp.length() == 0) { old = -1; } else { try { old = Integer.parseInt(tmp); } catch (NumberFormatException e) { old = -1; } } String tmps[] = request.getParameterValues("food"); String food = ""; if (tmps != null) { for (int i = 0; i < tmps.length; i++) { food += decodeString(tmps[i]); food += " "; } } else { food = "ありません"; } StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<p>お名前は "); sb.append(name); sb.append(" です</p>"); sb.append("<p>年齢は "); if (old == -1) { sb.append("未設定です</p>"); } else { sb.append(old); sb.append(" です</p>"); } sb.append("<p>好きな果物は "); sb.append(food); sb.append("です</p>"); sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } protected String decodeString(String str) { try { byte[] byteData = str.getBytes("ISO-8859-1"); str = new String(byteData, "UTF-8"); } catch (UnsupportedEncodingException e) { return null; } return str; } } ``` **RequestSample2.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <p>アンケート調査です</p> <form action="RequestSample2" method="get"> <table> <tr> <td>氏名</td> <td><input type="text" size="20" value="" name="name"></td> </tr> <tr> <td>年齢</td> <td><input type="text" size="5" value="" name="old"></td> </tr> <tr> <td>好きな果物</td> <td><select name="food" size="3" multiple> <option value="りんご">りんご</option> <option value="メロン">メロン</option> <option value="ぶどう">ぶどう</option> </select></td> </tr> </table> <input type="submit" name="button1" value="送信"> </form> </body> </html> ``` #### **実行結果** <!--graph5-2.png --> <img src="https://i.loli.net/2019/06/27/5d14799d89cc859217.png" width="40%"/> <br> 日本語が含まれるパラメータを処理する方法として「setCharacterEncoding」メソッドを使う方法を確認します。「HttpServletRequest」インターフェースの親インターフェースの「ServletRequest」インターフェースで定義されています。<br> もともと文字化けする原因が、パラメータとして送られてきたバイト列から文字列に変換する時に、文字コードとして「ISO-8859-1(Latin1)」を使ってしまうのが問題でした。そこで正しい文字コードをサーブレットに事前に設定が出来れば文字化けは発生しません。<br> 「**setCharacterEncoding**」メソッドはリクエストボディに含まれるデータの文字コードを指定した値に書き換えるメソッドです。 **setCharacterEncoding** ``` public void setCharacterEncoding(java.lang.String env) throws java.io.UnsupportedEncodingException ``` 例えば次のように使います。 ``` public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ request.setCharacterEncoding("Utf-8"); String val = request.getParameter("name"); } } ``` 極めてスマートに文字化けが回避出来るのですが、このメソッドではリクエストボディに含まれるデータの文字コードしか設定できません。「POST」メソッドを使った場合にはクライアントから送られてくるパラメータはリクエストボディに含まれるので問題ありませんが、「GET」メソッドを使った場合にはパラメータはURIの部分に含まれています。その為「setCharacterEncoding」メソッドを使ってもパラメータの文字コードの設定は行えませんので注意してください。<br> フォームが含まれるHTMLページは、送信方法を「POST」にしたものを使います。<br> #### **例** **RequestSample3.java** ``` package hello; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RequestSample3") public class RequestSample3 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); String tmp; String name = ""; tmp = request.getParameter("name"); if (tmp == null || tmp.length() == 0) { name = "未設定です"; } else { name = tmp; } int old; tmp = request.getParameter("old"); if (tmp == null || tmp.length() == 0) { old = -1; } else { try { old = Integer.parseInt(tmp); } catch (NumberFormatException e) { old = -1; } } String tmps[] = request.getParameterValues("food"); String food = ""; if (tmps != null) { for (int i = 0; i < tmps.length; i++) { food += tmps[i]; food += " "; } } else { food = "ありません"; } StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<p>お名前は "); sb.append(name); sb.append(" です</p>"); sb.append("<p>年齢は "); if (old == -1) { sb.append("未設定です</p>"); } else { sb.append(old); sb.append(" です</p>"); } sb.append("<p>好きな果物は "); sb.append(food); sb.append("です</p>"); sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } } ``` **RequestSample3.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <p>アンケート調査です</p> <form action="RequestSample3" method="post"> <table> <tr> <td>氏名</td> <td><input type="text" size="20" value="" name="name"></td> </tr> <tr> <td>年齢</td> <td><input type="text" size="5" value="" name="old"></td> </tr> <tr> <td>好きな果物</td> <td><select name="food" size="3" multiple> <option value="りんご">りんご</option> <option value="メロン">メロン</option> <option value="ぶどう">ぶどう</option> </select></td> </tr> </table> <input type="submit" name="button1" value="送信"> </form> </body> </html> ``` #### **実行結果** <!--graph5-3.png --> <img src="https://i.loli.net/2019/06/27/5d147a7af357055159.png" width="40%" /> <br> ## **6.パラメータ名の取得(getParameterNames)** リクエストに含まれるパラメータ名を取得する必要はあまりありませんが、デバックなどの目的で送付されてきたパラメータを取得したい場合には「HttpServletRequest」インターフェースの親インターフェースの「ServletRequest」インターフェースで定義されている「getParameterNames」メソッドを使います。 **getParameterNames** ``` public java.util.Enumeration getParameterNames() ``` 例えば次のように使います。 ``` public class Sample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ Enumeration names = request.getParameterNames(); while (names.hasMoreElements()){ String name = (String)names.nextElement(); } } } ``` <br> ## **7.リクエストURIの取得(getRequestURI)** サーブレットが呼ばれた時のURIを取得する方法を確認します。(ただし、ここでURIやURLと読んでいるものは一般的に言われている厳密なものとは若干異なります)。<br> リクエストのURIを取得するには「HttpServletRequest」インターフェースで定義されている「getRequestURI」メソッドを使います。 **getRequestURI** ``` public java.lang.String getRequestURI() ``` このメソッドでは、リクエストに含まれるポート番号とパラメータの間の部分を取得出来ます。つまりコンテキストパス+サーブレットパスの部分です。<br> またリクエストの中のサーブレット名だけを知りたい場合には「getServletPath」メソッドを使います。 **getServletPath** ``` public java.lang.String getServletPath() ``` このメソッドではサーブレットパスの部分でけを取得できます。 またURLそのものを取得したい場合には「getRequestURL」メソッドを使います。 **getRequestURL** ``` public java.lang.StringBuffer getRequestURL() ``` このメソッドの場合はURL形式で取得が出来ます。ただし、このメソッドでもクエリー文字列のパラメータ部分は取得されません。また戻り値がStringBufferクラスのオブジェクトになっていますので注意が必要です。<br> 今回はサーブレットを直接呼び出してリクエストから各種情報を取り出してみます。<br> #### **例** **RequestSample4.java** ``` package hello; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RequestSample4") public class RequestSample4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>テスト</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<p>"); sb.append("getRequestURL:"); sb.append(new String(request.getRequestURL())); sb.append("</p>"); sb.append("<p>"); sb.append("getRequestURI:"); sb.append(request.getRequestURI()); sb.append("</p>"); sb.append("<p>"); sb.append("getServletPath:"); sb.append(request.getServletPath()); sb.append("</p>"); sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } } ``` #### **実行結果** <!--graph5-4.png --> <img src="https://i.loli.net/2019/06/27/5d147b59d001a76720.png" width="40%"/> <br> ## **8.getInitParameterメソッド** **< init-param >要素**<br> 少し戻りますが<sevlet>要素には子要素として<init-param>要素を定義することができます。<init-param>要素はサーブレットに初期値を設定したい場合に利用します。 ``` <web-app> <servlet> <servlet-name> サーブレット名 </servlet-name> <servlet-class> 実際のクラス名 </servlet-class> <init-param> <param-name> パラメータ名1 </param-name> <param-value> パラメータ値1 </param-value> </init-param> <init-param> <param-name> パラメータ名2 </param-name> <param-value> パラメータ値2 </param-value> </init-param> </servlet> </web-app> ``` ``` <servlet> <servlet-name>Sample</servlet-name> <servlet-class>SampleServlet</servlet-class> <init-param> <param-name> url</param-name> <param-value>jdbc:mysql://localhost:3306/companydata?serverTimezone=JSTl</param-value> </init-param> <init-param> <param-name> username</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>driverClassName</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </init-param> </servlet> ``` < param-name >で設定名、< param-value >で値を指定します。これらの値を読み取るには、「getInitParameter」メソッド(「GenericServlet」クラスで定義)を使用します。 ``` public void init() throws ServletException { url = getInitParameter("url"); username = getInitParameter("username"); password = getInitParameter("password"); driverClassName = getInitParameter("driverClassName"); } ```
content
戻る