6 Servlet | forward/redirect

Choi jeongmin·2024년 10월 17일

Servlet

목록 보기
7/7

1. forward

기본적으로 변수의 기본 스코프는 메소드 이기 때문에
다른 페이지(서블릿) 로 데이터를 공유할 수 없다.
하지만 forward 방식은 request 와 response 를 포함하여 위임하므로
request 에 정보를 저장하여 forward 하면 위임받은 서블릿에서도
위임한 서블릿의 정보를 받아올 수 있다.
forward 받은 서블릿의 존재를 클라이언트가 알 필요가 없기 때문에
url 자체는 변경되지 않는다.
forward 방식의 또 다른 특징은 요청 시 서버로 전송한 데이터가
남아있는 상태로 새로고침(재요청)을 하면 동일한 요청을 반복하여
데이터베이스에 insert 하는 등의 행위 등이 중복된 행이 삽입될 가능성이 있다.
따라서 그런 경우는 다른 페이지 전환 방식인 redirect 를 이용한다.

package com.ohgiraffers.section01.forward;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/forward")
public class ReceiveInformationServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        String userId = req.getParameter("userId");
        String password = req.getParameter("password");

        System.out.println("userId = " + userId);
        System.out.println("password = " + password);

        // 다른 서블릿으로 데이터를 request 의 setAttribute 로 전달한다.
        req.setAttribute("userId", userId);

        // print 라는 경로로 요청을 넘기기 위한 객체 생성
        // 이 경로는 서블릿이나 JSP 모두 가능
        RequestDispatcher rd = req.getRequestDispatcher("print");

        rd.forward(req, resp);


    }
}

위의 /forward 서블릿에서 속성을 포워드해서 /print에서 뿌려준다.

package com.ohgiraffers.section01.forward;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

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

@WebServlet("/print")
public class PrintLoginSuccessServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String userId = (String)req.getAttribute("userId");
        System.out.println(userId);

        String userId2 = req.getParameter("userId");
        System.out.println(userId2);

        // 응답에 필요한 데이터가 준비되면 동적인 웹 페이지를 생성한다.
        StringBuilder responseText = new StringBuilder();
        responseText.append("<!DOCTYPE html>\n")
                .append("<html>\n")
                .append("<head>\n")
                .append("</head>\n")
                .append("<body>\n")
                .append("<h3 align=\"center\">")
                .append(userId)
                .append("님 환영합니다. </h3>\n")
                .append("</body>\n")
                .append("</html>");

        resp.setContentType("text/html; charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.print(responseText);
        out.flush();
        out.close();
        
    }
}

2. redirect

redirect 하면 url 이 재작성되어 새로고침할 때 redirect 된 페이지에 대한 요청을 반복한다.
즉, 이전 요청에 포함된 정보는 남아있지 않고, url 이 변경되는 것이 redirect 의 특징이다.
첫 요청 시의 request 와 현재 redirect 된 페이지의 request 는 서로 다른 객체이므로
redirect 를 쓰면 이전 서블릿의 값을 공유해서 사용할 수 없다.
http 요청은 요청 시 잠시 connection 을 맺고 응답 시에도 잠시 connection 을 맺으며
요청 단위 당 request 객체는 한 개만 생성된다.

  • 다른 사이트로 리다이렉트
package com.ohgiraffers.section01.othersite;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/othersite")
public class OtherSiteRedirectServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get 요청 후 naver 로 redirect");

        resp.sendRedirect("https://www.naver.com");
    }
}
  • 다른 서블릿으로 리다이렉트
package com.ohgiraffers.section02.otherservlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/otherservlet")
public class OtherServletRedirectTest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("get 요청 정상 수락");
        System.out.println(resp); // org.apache.catalina.connector.ResponseFacade@5c5717be
        resp.sendRedirect("redirect");
    }
}
  • otherservlet 서블릿에서 redirect 서블릿으로 리다이렉트
package com.ohgiraffers.section02.otherservlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

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

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {

    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("이 서블릿으로 redirect 성공");
        System.out.println(resp); // org.apache.catalina.connector.ResponseFacade@70daeadb

        resp.setContentType("text/html; charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.print("<h1>이 서블릿으로 redirect 성공</h1>");
        out.flush();
        out.close();
        
        
    }

}

0개의 댓글