끵뀐꿩긘의 여러가지

[부스트코스]웹 프로그래밍 24. redirect & forward 본문

부스트코스 - 웹/2. DB 연결 웹 앱

[부스트코스]웹 프로그래밍 24. redirect & forward

끵뀐꿩긘 2020. 3. 20. 13:42

리다이렉트 (redirect)

  • 리다이렉트는 HTTP프로토콜로 정해진 규칙이다.
  • 서버는 클라이언트의 요청에 대해 특정 URL로 이동을 요청할 수 있다. 이를 리다이렉트라고 한다.
  • 서버는 클라이언트에게 HTTP 상태코드 302로 응답하는데 이때 헤더 내 Location 값에 이동할 URL 을 추가한다. 클라이언트는 리다이렉션 응답을 받게 되면 헤더(Location)에 포함된 URL로 재요청을 보내게 된다. 이때 브라우저의 주소창은 새 URL로 바뀌게 된다..
  • 클라이언트는 서버로부터 받은 상태 값이 302이면 Location헤더값으로 재요청을 보내게 된다. 이때 브라우저의 주소창은 전송받은 URL로 바뀌게 된다.
  • 서블릿이나 JSP는 리다이렉트하기 위해 HttpServletResponse 클래스의 sendRedirect() 메소드를 사용한다.

예제)

 

redirect01.jsp

1
2
3
4
5
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    response.sendRedirect("redirect02.jsp");
%>    
cs

 

redirect02.jsp

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
redirect된 페이지 입니다.
</body>
</html>
cs

결과: 

리다이렉트

리다이렉트가 필요한 이유

리다이렉트는 사용하기 나름이지만 네이버 카페를 예로 들어 보겠습니다.

카페마다 다르겠지만 특정 네이버 카페의 글들은 네이버 회원이라고 하더라도 해당 카페에 가입되어 있거나 혹은 카페에 가입되어 있다고 하더라고 특정 등급이 되어야 열람할 수 있는 글들이 있습니다.

 

만약 해당 글의 URL을 알아내어 브라우저의 주소창에 입력한 후 접근한다고 했을때 권한이 없다면 글에 대한 내용을 웹서버가 응답하면 안될 것입니다. 이때 웹서버는 글에 접근하는 요청마다 권한을 검사하고 권한이 되지 않는 경우 권한을 확인하세요 라는 경고 문구가 뜨는 페이지나 혹은 네이버 계정이 로그인 되어 있지 않은 상태라면 로그인 페이지로 리다이렉트 시킬 필요가 있습니다.

출처: https://dololak.tistory.com/147 [코끼리를 냉장고에 넣는 방법]

 


forward란?

  1. 웹 브라우저에서 Servlet1에게 요청을 보냄
  2. Servlet1은 요청을 처리한 후, 그 결과를 HttpServletRequest에 저장
  3. Servlet1은 결과가 저장된 HttpServletRequest와 응답을 위한 HttpServletResponse를 같은 웹 어플리케이션 안에 있는 Servlet2에게 전송(forward)
  4. Servlet2는 Servlet1으로 부터 받은 HttpServletRequest와 HttpServletResponse를 이용하여 요청을 처리한 후 웹 브라우저에게 결과를 전송

forward

예제)

<FrontServlet에서 NextSevlet로 forward 후 결과 출력>

 

  • service 메소드만 호출하여 FrontServlet servlet을 생성.
  • request객체의 setAttribute 메소드를 통해 dice를 request scope에 저장
  • request.getRequestDispatcher.forward를 통해 request,response를 NextServlet 서블렛에 forward
  • NextServlet에서 request 객체의 getAttribute 메소드를 통해 dice값 얻음

*getRequestDispatcher()가 실행되는 순간 지정된 페이지를 읽어들여서 리다이렉트 시킨다. 서버단에서 모든 작업이 이루어진다. getRequestDispatcher() 이후 코드는 실행되지 않고 무시된다. request, response 를 리다이렉트 시키는 페이지에 전달해서 사용할 수 있다.

 

FrontServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package examples;
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;
 
/**
 * Servlet implementation class FrontServlet
 */
@WebServlet("/front")
public class FrontServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FrontServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
    */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            int diceValue = (int)(Math.random() * 6+ 1;
            request.setAttribute("dice", diceValue);
            
            RequestDispatcher requestDispatehcer = request.getRequestDispatcher("/NextServlet.java");
            requestDispatehcer.forward(request, response);
    }
 
}
cs

 

NextSevlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package examples;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class ForwardServlet
 */
@WebServlet("/forward")
public class ForwardServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ForwardServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head><title>form</title></head>");
        out.println("<body>");
 
        int dice = (Integer)request.getAttribute("dice");
        out.println("dice : " + dice);
        for(int i = 0; i < dice; i++) {
            out.print("<br>hello");
        }
        out.println("</body>");
        out.println("</html>");
    }
 
}
cs

random 함수에서 생성된 난수에 따라 dice값과 hello의 횟수가 바뀐다.

두개의 코드가 다른 파일(servlet)에 있지만, forward를 통해 객체를 보내고 받아서 결과를 출력하였다.


Servlet과 JSP연동

  • Servlet은 프로그램 로직이 수행되기에 유리하다. IDE 등에서 지원을 좀 더 잘해준다.
  • JSP는 결과를 출력하기에 Servlet보다 유리하다. 필요한 html문을 그냥 입력하면 됨.
  • 프로그램 로직 수행은 Servlet에서, 결과 출력은 JSP에서 하는 것이 유리하다.
  • Servlet과 JSP의 장단점을 해결하기 위해서 Servlet에서 프로그램 로직이 수행되고, 그 결과를 JSP에게 포워딩하는 방법이 사용되게 되었다. 이를 Servlet과 JSP연동이라고 한다.

*JSP가 Servlet에서 발전된 방식이라기보단 어디에 특화되었는지에 따라 나눈것이라 볼 수 있다.

JSP - presentation 담당

Servlet - data processing 담당

 

Servlet forwarding JSP

setAttribute, request.getRequestDispatcher,getAttribute메소드를

사용하여 Servlet과 JSP를 연동한다.

 

summary)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        request.setAttribute("v1", v1);
        request.setAttribute("v2", v2);
        request.setAttribute("result", result); 
        //<변수입력>
        //setAttribute 사용법: request.setAttribute(name,variable); 
        
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/result.jsp");
        requestDispatcher.forward(request, response);
        //<forwarding>
        //request.getRequestDispatcher 사용법:
        //RequestDispatcher VARNAME = request.getRequestDispatcher("주소");
        //VARNMAE.forward((request, response); --> request, response값 fowarding''
 
        <%
            int v1 = (int)request.getAttribute("v1");
            int v2 = (int)request.getAttribute("v2");
                int result = (int)request.getAttribute("result");
        %>
        //<JSP에서 변수 받기>
        //getAttribute 사용법:
        // VAR = (DATATYPE)request.getAttribute(NAME);
cs

Comments