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(요청)에 값을 저장할 수 있게 되었다. 이 후에는 포워드를 사용하여 JSP에 표시를 바꿀 뿐이다. 이 처리는 의외로 귀찮은 일이다. 다음에 같이 정리된다.

  1. ServletContext를 얻기
ServletContext app = this.getServletContext();

ServletContext이라는 것은 현재 움직이고 있는 Web 애플리케이션을 관리하기 위한 것이다. 이 인스턴스에는 Web 어플리케이션의 중요한 기능을 포함되어 있다.

  1. RequestDispatcher를 얻기
RequestDispatcher dispatcher = app.getRequestDispatcher("/ hello.jsp");

ServletContext에서 “RequestDispatcher"라는 인스턴스를 가져온다. 이것은 요청를 디스패치(다른 곳으로 보내는 것)하는 것이다. 아무튼, 우선은 “이 가운데, 포워드가 이 메소드으로 제공된다"라는 점만 기억하면 된다.

  1. forward 메소드로 포워드하기
try {
    dispatcher.forward(request, response);
} catch (ServletException e) {
    out.println(e);
}

취득한 RequestDispatcher에 제공하고 있는 “forward"로 포워드가 실행된다. 인수는 HttpServletRequest와 HttpServletResponse를 지정한다. 이 두개의 인수는 모두 doGet/doPost에 인수로 전달된 인스턴스를 그대로 설정하면 된다.

포워드는 forward라는 메소드에서 실행되지만, 그것을 호출까지 여러 인스턴스를 가져와야 한다. ServletContext와 RequestDispatcher를 얻어와서, 그 안에 메소드를 호출하여 포워드가 실행되는 것이다.