JSP/Servlet | サーブレットとJSP/HTML | JSPに渡して結果をforwardで表示する

もう一つの方法は、フォワードによって結果を表示するJSPへ表示を切り替えることである。サーブレットから結果を表示するJSPへforwardすれば、サーブレット側で画面表示などを行う必要はない。

ただし、この方法を使う場合、「サーブレットからフォワード先のJSPへ結果データをどのように渡すか」を考える必要がある。これもサンプルを見ながら説明する。

hello.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sample jsp</title>
<style>
h1{
    font-size: 16pt;
    background: #AAFFAA;
    padding: 5px;
}
</style>
</head>
<body>
    <h1>Hello App Engine!</h1>
    <p>Result : <%=request.getAttribute("result") %></p>
    <hr>
    <p id="msg">整数入力: </p>
    <form method="post" action="/mygaeapp">
    <table>
        <tr>
            <td>入力</td>
            <td><input type="text" id="input" name="text1" value="<%=request.getAttribute("input") %>"></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="送信"></td>
        </tr>
    </table>
    </form>
</body>
</html>

MyGaeAppServlet.java

package com.devkuma.mygaeapp;

import java.io.*;
import java.net.URLDecoder;

import javax.servlet.*;
import javax.servlet.http.*;

@SuppressWarnings("serial")
public class MyGaeAppServlet3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/plain");
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        PrintWriter out = response.getWriter();
        out.println("Hello, world!");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        String param = URLDecoder.decode(request.getParameter("text1"), "utf8");
        PrintWriter out = response.getWriter();
        int result = 0;
        try {
            int n = Integer.parseInt(param);
            for (int i = 1; i <= n; i++) {
                result += i;
            }
        } catch (NumberFormatException e) {
            out.println(e);
        }
        request.setAttribute("input", param);
        request.setAttribute("result", result);
        ServletContext app = this.getServletContext();
        RequestDispatcher dispatcher = app.getRequestDispatcher("/hello.jsp");
        try {
            dispatcher.forward(request, response);
        } catch (ServletException e) {
            out.println(e);
        }
    }
}

上はフォームを持つJSPと、その送信先となるサーブレットのソースコードである。hello.jspにアクセスしてフォームに整数を書いて送信すると、/mygaeappへPOSTで送信され、そのままhello.jspへ転送される。このとき、「Result: OO」のようにサーブレットで合計した結果が表示される。

ここではサーブレットからJSPへ必要な値を渡すために、次のような処理を行っている。

サーブレットで値を保存する

request.setAttribute("input", param);
request.setAttribute("result", result);

JSPで値を取り出す

<%=request.getAttribute("result") %>
<%=request.getAttribute("input") %>

requestはHttpServletRequestクラスのインスタンスである。このsetAttributeメソッドを呼び出すことで、HttpServletRequest内に値を保存できる。これはgetAttributeメソッドでいつでも取り出せる。これらのメソッドの使い方をまとめると次のようになる。

値の保存

"HttpServletRequest".setAttribute(名前, 値);

値の取得

変数 = "HttpServletRequest".getAttribute(名前);

これでHttpServletRequest、つまりリクエストに値を保存できるようになった。あとはforwardを使ってJSPに表示を切り替えるだけである。この処理は意外と面倒である。次のように整理される。

  1. ServletContextを取得する
ServletContext app = this.getServletContext();

ServletContextとは、現在動作しているWebアプリケーションを管理するためのものである。このインスタンスにはWebアプリケーションの重要な機能が含まれている。

  1. RequestDispatcherを取得する
RequestDispatcher dispatcher = app.getRequestDispatcher("/hello.jsp");

ServletContextからRequestDispatcherというインスタンスを取得する。これはリクエストをディスパッチ、つまり別の場所へ送るものである。まずは、この中でforwardがメソッドとして提供されていると覚えておけばよい。

  1. forwardメソッドでフォワードする
try {
    dispatcher.forward(request, response);
} catch (ServletException e) {
    out.println(e);
}

取得したRequestDispatcherが提供しているforwardでフォワードが実行される。引数にはHttpServletRequestとHttpServletResponseを指定する。この2つの引数は、どちらもdoGet/doPostに引数として渡されたインスタンスをそのまま設定すればよい。

フォワードはforwardメソッドで実行されるが、それを呼び出すまでにいくつかのインスタンスを取得する必要がある。ServletContextとRequestDispatcherを取得し、その中のメソッドを呼び出してフォワードを実行するのである。