JAVA/JSP

[JSP] Forward와 Redirect

로아다 2023. 6. 19. 11:58
728x90
반응형
Forward

- 사용자가 보낸 요청을 해당 서블릿에서 처리하다가 요청 정보를 다른 서블릿으로 넘겨 이어받아 처리하게 하는 것

- 사용자가 보낸 요청 객체를 그대로 다음 서블릿으로 전달하기 때문에 요청에 실려있던 파라미터들도 그대로 함께 전달된다.

- 이 포워들를 이용하여 자바 코드가 많이 사용되는 처리(controller, service)는 서블릿에서 진행하고, html 코드가 많이 사용되는 처리(view) JSP에서 이어서 진행할 수 있다.

        <h3># forward</h3>

        <form id="form1" action="/chap03/forwardtest" method="POST"></form>
                <input type="text" name="type" value="drink" form="form1"/>
                <input type="text" name="name" value="Americano" form="form1"/>
                <input type="text" name="price" value="7000" form="form1"/>
                <input type="text" name="qty" value="5" form="form1"/>
                <input type="submit" value="보내기" form="form1"/>

 

Redirect

- 요청 보낸 클라이언트가 다른 주소로 다시 요청하라고 응답하는 것

- 리다이렉트 응답을 받은 클라이언트(웹 브라우저)에서는 새로운 요청을 만들어 보내기 때문에 이전 요청에 보냈던 파라미터는 기본적으로는 남아있을 없다.

        <h3># redirect</h3>
        
        <form id="form2" action="/chap03/redirect_test" method="POST"></form>
                <input type="text" name="type" value="drink" form="form2"/>
                <input type="text" name="name" value="Americano" form="form2"/>
                <input type="text" name="price" value="7000" form="form2"/>
                <input type="text" name="qty" value="5" form="form2"/>
                <input type="submit" value="보내기" form="form2"/>

 

forward의 용도

- 서블릿은 자바 코드를 작성하기에 편리하고 JSP는 html 코드를 작성하기에 편리하다.

- 하나의 요청에 대해서 1차로 서블릿에서 자바로 처리를 모두 마친 후 포워드를 통해 2차로 html 코드를 생성하여 응답하는 방식을 많이 사용한다.

- 이것을 view와 controller의 분리라고 한다.

- 실제 view 페이지의 경로가 노출되는 것이 아니라 forward를 보낸 서블릿의 주소가 그대로 유지된다. (확장자를 감출 수 있다.)

package chap03.servlet;

import java.io.IOException;

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

@WebServlet("/forwardtest")
public class ForwardServlet extends HttpServlet {
        
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 자바로 처리하고 싶은 내용들을 처리한다..
                String type = req.getParameter("type");
                String name = req.getParameter("name");
                String price = req.getParameter("price");
                String qty = req.getParameter("qty");
                
                int total_price = 0;
                
                // String으로 받은 데이터를 활용할 때 null이 들어있을 것을 대비해야 한다.
                if (price != null && qty != null) {
                        System.out.printf("%s(%s) / %d\n", 
                                name, type, total_price = (Integer.parseInt(price) * Integer.parseInt(qty)));
                } else {
                        // 하나라도 null값이 존재하면 정상적인 접근이 아니므로
                        // 다시 index.jsp로 요청하라고 응답을 보낼 수 있다.
                        resp.sendRedirect("/chap03/forward/index.jsp");
                        return;
                }
                
                // 처리 후 얻어낸 결과를 다음 서블릿까지 전달하고 싶을 때는
                // request 객체에 데이터를 실어 보낼 수 있다. (attribute)
                req.setAttribute("full_name", String.format("%s(%s)", name, type));
                req.setAttribute("total_price", total_price);
                
                // 요청을 다른 곳으로 넘기기 위한 기능들이 들어있는 객체
                // forward : 요청 객체를 다른 곳으로 넘겨 처리한 후 그곳에서 응답한다.
                // include : 요청 객체를 다른 곳으로 넘겨 처리한 후 다시 돌아온다.
                RequestDispatcher dispatcher =
                        req.getRequestDispatcher("/forward/view.jsp");
                
                dispatcher.forward(req, resp);
        }
}

 

redirect의 용도

- 사용자가 정상적이지 않은 방법으로 접속한 경우를 막기 위해 사용

- 사용자가 요총에 함께 실어보냈던 데이터들을 새로고침으로 재사용하지 못하도록 막는 용도

- ex> 사용자가 글을 쓴 후에 새로고침으로 같은 글이 계속 등록되는 것은 막아야한다.

package chap03.servlet;

import java.io.IOException;

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

@WebServlet("/redirect_test")
public class RedirectServlet extends HttpServlet{
   
   @Override
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      
      // 클라이언트에게 다른 주소로 다시 요청하라고 응답
      // 사용자의 웹 브라우저에서 필요한 경로를 전달해야 한다
      
      // 요청 객체를 그대로 전달하는 것이 아니라
      // 새 요청을 보내도록 하는 것이기 때문에 데이터가 유지되지 않는다
      resp.sendRedirect("/chap03/forward/view.jsp");
   }
}

 

request의 attribute

- 첫 번째 서블릿에서 얻어낸 처리 결과물을 view 페이지에서 사용하고 싶을 때 요청 객체의 attribute에 실어 보낼 수 있다.

- 파라미터와 마찬가지로 Key-Value 방식을 사용한다.

- 실어놓을 때 : setAttribute("key", value)

- 꺼낼 때 : getAttribute("key")

- 어트리뷰트에 실어 놓은 값은 꺼낼 때 해당 타입이 Object로 나온다. (필요하다면 다운 캐스팅하여 원래대로 사용할 수 있다.)

 

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>보여지는 페이지</title>
</head>
<body>

        비즈니스 로직 처리가 모두 끝난 후 보여지는 페이지
        (사용자 눈에 보여지는 곳, view)
        
        <hr> 
        
        <h3># 이전 서블릿으로부터 넘겨받은 데이터들</h3>
        
        풀 네임: <%= request.getAttribute("full_name") %>
        총 가격 : <%= request.getAttribute("total_price") %>

</body>
</html>
728x90
반응형