[Servlet] 서블릿 포워드

Bam·2024년 5월 4일
0

Spring

목록 보기
22/48
post-thumbnail

Servlet Forward

포워드(Forward)는 추가 작업을 다른 서블릿에게 수행하게 하거나, 요청에 대한 정보를 다른 서블릿/JSP와 공유하는 등의 용도로 다양하게 사용되는 기술입니다. 간단히 요약하면 포워드는 한 서블릿에서 다른 서블릿이나 JSP로 요청(데이터)를 전달하는 기술이라고 할 수 있습니다.

4가지 포워드 방식

포워드를 구현하는 방식에는 redirect, Refresh, location, dispatch 4가지 방식이 있습니다.

redirect

  • HttpServletResponse.sendRedirect() 메소드 이용
  • 웹 브라우저에 재요청
  • sendRedirect("포워드 대상")

redirect는 서블릿 요청이 클라이언트를 거쳐 다시 요청되는 방식입니다.

ServletA, ServletB 두 개의 서블릿을 생성합니다. A에서 B를 요청합니다.

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/a")
public class ServletA extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html><body><h1>ServletA</h1></body></html>");

        resp.sendRedirect("b");	//웹 브라우저에 다른 서블릿인 b를 요청
    }
}
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/b")
public class ServletB extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html><body><h1>ServletB</h1></body></html>");
    }
}

톰캣 서버를 실행해서 http://localhost:8090/a로 들어가게되면 바로 /b로 리다이렉트 됨을 볼 수 있습니다.

redirect 방식을 이용할 때 다른 서블릿/JSP으로 데이터를 전달할 수도 있습니다.

resp.sendRedirect("b?id=b1");

GET 메소드의 키-값 쌍을 전달함으로써 데이터를 다른 서블릿/JSP로 데이터를 전달할 수 있습니다.

Refresh

  • HttpServletResponse.addHeader() 메소드 이용
  • 웹 브라우저에 재요청
  • response.addHeader("Refresh", 경과시간, url=요청할_서블릿/JSP)

Refresh 방식도 redirect 방식과 유사하게 서블릿 요청이 클라이언트를 거쳐 다시 요청됩니다. 앞에서 작성한 ServletA의 redirect 부분을 주석처리하고 아래와 같이 Refresh 포워딩 코드를 삽입합니다.

@WebServlet("/a")
public class ServletA extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html><body><h1>ServletA</h1></body></html>");

        //resp.sendRedirect("b");	redirect 포워딩
        resp.addHeader("Refresh", "1;url=/b");
    }
}

경과시간 단위는 로 위 코드에선 1초로 지정되었기 때문에 http://localhost:8090/a에 접속하면 1초 후 http://localhost:8090/b로 이동됩니다.

location

  • 자바스크립트 location 객체의 href 속성 사용
  • 자바스크립트에서 재요청
  • location.href='요청할 서블릿, JSP';

location은 자바스크립트의 객체 중 하나입니다. location.href의 속성값으로 요청하고자하는 서블릿/JSP를 지정하면 포워딩하게 됩니다.

PrintWriter를 이용해서 <script>태그로 감싼 자바스크립트 코드를 전달합니다.

@WebServlet("/a")
public class ServletA extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html><body><h1>ServletA</h1></body></html>");

        //resp.sendRedirect("b");   redirect 포워딩
        //resp.addHeader("Refresh", "1;url=/b");    Refresh 포워딩
        out.print("<script type=\"text/javascript\">location.href=\"b\";</script>");
    }
}

마찬가지로 http://localhost:8090/a를 입력하면 바로 http://localhost:8090/b로 이동함을 볼 수 있습니다.

dispatch

  • 포워딩이라고 하면 일반적으로 사용되는 방식
  • 서블릿이 직접 요청
  • RequestDispatcher.forward() 메소드 이용

dispatch 포워딩은 앞에서 본 redirect, Refresh와는 다르게 요청이 클라이언트를 거치지 않고 서버 내에서 포워딩이 바로 진행된다는 점 입니다.

@WebServlet("/a")
public class ServletA extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html><body><h1>ServletA</h1></body></html>");

        //resp.sendRedirect("b");   redirect 포워딩
        //resp.addHeader("Refresh", "1;url=/b");    Refresh 포워딩
        //out.print("<script type=\"text/javascript\">location.href=\"b\";</script>");  location 포워딩
        RequestDispatcher dispatcher = req.getRequestDispatcher("b");
        dispatcher.forward(req, resp);
    }
}

역시 http://localhost:8090/a로 접속하면 다음과 같은 결과가 나옵니다. 결과는 /b지만 url은 그대로 /a죠? 이는 dispatch가 위 그림대로 서버에서 포워딩이 실행되기 때문에 나타나는 결과입니다.

dispatch 방식도 GET 메소드의 키-값 쌍을 통해 다른 서블릿/JSP로 데이터를 전달할 수 있습니다.

RequestDispatcher dispatcher = req.getRequestDispatcher("b?id=b1");
dispatcher.forward(req, resp);

0개의 댓글