본문 바로가기
Back/Servlet

서블릿 포워드(Servlet Forward)

by Hyeon_ 2021. 12. 29.

서블릿 포워드

포워드(forward)란?

  • 하나의 서블릿이 다른 서블릿이나 JSP와 연동하는 방법

서블릿 포워드 기능

  • 서블릿에서 다른 서블릿이나 JSP, 웹 브라우저로 요청을 전달하는 기능
  • 요청에 대한 추가 작업을 다른 서블릿에게 수행하게 하는 역할
  • 요청에 포함된 정보를 다른 서블릿이나 JSP와 공유
  • 요청에 정보를 포함시켜 다른 서블릿에게 전달
  • 모델2 개발 시 서블릿에서 JSP로 데이터를 전달하는 데 사용

서블릿 포워드 방법

  1. redirect
    • HttpServletResponse 객체의 sendRedirect() 메소드 사용
    • 웹 브라우저에게 재요청하는 방식
    • 형식 : sendRedirect("포워드할 서블릿 또는 JSP");
  2. refresh
    • HttpServletResponse 객체의 addHeader() 메소드 사용
    • 웹 브라우저에게 재요청하는 방식
    • 형식 : response.addHeader("Refresh", 경과시간(초); url=요청할 서블릿 또는 JSP);
  3. location
    • 자바스크립트 location 객체의 href 속성 이용
    • 자바스크립트에서 재요청하는 방식
    • 형식 : location href = "요처어할 서블릿 또는 JSP";
  4. dispatch
    • 일반적으로 포워딩 기능 지칭
    • 서블릿이 직접 요청하는 방식
    • URL이 바뀌지 않음
    • RequestDispatcher 클래스의 forward() 메소드 사용
    • 형식
      • RequestDispatcher dis = request.getRequestDispathcer("포워드할 서블릿 또는 JSP");
      • dis.forward(request, response);

dispatch는 서블릿의 이동이 있어도 url의 변경이 일어나지 않음

ex) /first 서블릿에서 /second 서블릿으로 이동해도 localhost:8080/first로 보임

다른 방식은 웹 브라우저를 거치기 때문에 url의 변경이 일어난다.


포워딩 예제 (GET 방식: URL 사용해서 포워딩)

서블릿 포워딩 - redirect

FirstServlet01
@WebServlet(name = "FirstServlet01", value = "/first01")
public class FirstServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("second01");
    }
}
SecondServlet01
@WebServlet(name = "SecondServlet01", value = "/second01")
public class SecondServlet01 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        out.println("<html><body>");
        out.println("sendRedirect를 이용한 redirect 포워딩");
        out.println("</body></html>");
    }
}

서블릿 포워딩 - Refresh

FirstServlet02
@WebServlet(name = "FirstServlet02", value = "/first02")
public class FirstServlet02 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.addHeader("Refresh", "2:url=second02");
        // addHeader("Refresh", "시간(초); url=매핑이름");
    }
}
SecondServlet02
@WebServlet(name = "SecondServlet02", value = "/second02")
public class SecondServlet02 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        out.println("<html><body>");
        out.println("refresh를 이용한 포워딩");
        out.println("</body></html>");
    }
}

서블릿 포워딩 - location

FirstServlet03
@WebServlet(name = "FirstServlet03", value = "/first03")
public class FirstServlet03 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // location을 이용한 포워딩
    // 자바스크립트의 location 객체 사용
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();

        out.println("<script type='text/javascript'>");
        out.println("location.href='second03'");
        out.println("</script>");
    }
}
SecondServlet03
@WebServlet(name = "SecondServlet03", value = "/second03")
public class SecondServlet03 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        out.println("<html><body>");
        out.println("location.href 객체를 이용한 포워딩");
        out.println("</body></html>");
    }
}

서블릿 포워딩 - 포워딩 하면서 데이터 전달(redirect)

FirstServlet04
@WebServlet(name = "FirstServlet04", value = "/first04")
public class FirstServlet04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("second04?name=hong");
    }
}
SecondServlet04
@WebServlet(name = "SecondServlet04", value = "/second04")
public class SecondServlet04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        // url 뒤에 붙어서 전송된 데이터 받기
        String name = request.getParameter("name");

        out.println("<html><body>");
        out.println("이름 : " + name);
        out.println("</body></html>");
    }
}

서블릿 포워딩 - dispatch (URL이 바뀌지 않음)

FirstServlet05
@WebServlet(name = "FirstServlet05", value = "/first05")
public class FirstServlet05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher distch = request.getRequestDispatcher("second05?name=lee");
        distch.forward(request, response);
    }
}
SecondServlet05
@WebServlet(name = "SecondServlet05", value = "/second05")
public class SecondServlet05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        // url 뒤에 붙어서 전송된 데이터 받기
        String name = request.getParameter("name");

        out.println("<html><body>");
        out.println("이름 : " + name);
        out.println("<br> dispatch 이용한 포워딩");
        out.println("</body></html>");
    }
}

전달하는 데이터의 양이 적을 경우에는 get 방식(ex. response.sendRedirect("서블릿이름?데이터이름=데이터값"))으로 데이터 값을 전달하면 되지만, 대량의 데이터를 공유하거나 전달하고 싶을 경우 바인딩 기능 사용

바인딩(Binding)

  • 웹 프로그래밍 실행 시 자원(데이터)를 서블릿 객체에 저장하는 방법
  • 주로 HttpServletRequest, HttpSession, ServletContext 객체에서 사용
  • 저장된 데이터는 서블릿이나 JSP에서 공유

바인딩 관련 메서드

  • setAttribute(String name, Object obj) : 자원을 각 객체에 바인딩
    • request.setAttribute로 사용
  • getAttribute(String name) : 각 객체에 바인딩된 자원을 name으로 가져옴
    • request.getAttribute로 사용
    • request.setAttribute에 담아온 내용 받아옴
  • removeAttribute(String name) : 각 객체에 바인딩된 자원을 name으로 제거

response.sendRedirect로는 request.setAttribute값 전달 불가

  • 첫 번째 전달된 서블릿의 request와 redirect를 통해 두 번째로 전달되는 서블릿의 request가 다르기 때문
  • dispatch는 request를 그대로 두 번째 서블릿으로 포워드하기 때문에 값을 받아올 수 있음​ dispatch.forward(request,response);
  • ex) RequestDispatcher dis = request.getRequestDispatcher("두번째 서블릿");