<< 학습 목표 >>
1. 포워딩하는 곳에서 포워딩을 받는 곳으로 데이터를 전달하기 위한 적절한 포워딩 방법을 선택할 수 있다.
2. 포워딩하는 곳에서 포워딩을 받는 곳으로 다양한 데이터를 전달할 수 있다.
포워딩을 할 때 포워딩을 하는 곳이 있고 포워딩을 받는 곳이 있음
포워딩을 하는 곳은 RequestDispatcher 를 사용하는 서블릿이고 포워딩을 받는 곳은 RequestDispatcher 에 명시된 HTML, JSP, 서블릿 등임
앞서 마지막에 만들었던 서블릿을 보자
포워딩을 하는 곳은 Login4 서블릿이고 포워딩을 받는 곳은 loginSuccess.html, login4.html 임
여기서는 포워딩을 받는 곳이 HTML 페이지 뿐이지만 JSP, 서블릿도 포워딩을 받을 수 있음
포워딩을 하는 곳에서 포워딩을 받는 곳으로 데이터를 전달해야할 때는 RequestDispatcher 를 사용하는게 바람직함
location.href, sendRedirect, addHeader 방식의 포워딩을 할 때도 포워딩을 받는 곳으로 데이터를 전달하기도 하지만 정말 어쩔 수 없는 경우이거나 잘못 사용하고 있을 가능성이 큼
location.href, sendRedirect, addHeader 방식의 포워딩을 할 때 포워딩을 받는 곳으로 데이터를 전달하지 말아야하는 이유는 이 세 방식은 데이터를 전달할 때 GET 방식으로 파라미터를 붙여서 데이터를 전달해야함
( 위 서블릿의 sendRedirect 를 잠깐 보고 오자 )
GET 방식의 특징 중 하나는 파라미터가 URL에 노출된다는 것
포워딩을 받는 곳에서 필요한 데이터가 중요한 개인 정보라거나 프로그램 동작에 민감한 영향을 미치는 데이터라면 사용자에게 그대로 노출되기 때문에 이 방식으로는 왠만하면 데이터를 전달하면 안됨
또 GET 방식의 특징 중 하나로 텍스트 밖에 전달할 수 없기 때문에 정보(객체)를 전달해야하는 경우에 전달할 수 있는 방법이 없음
RequestDispatcher 를 사용해 데이터를 전달하면 브라우저의 URL이 바뀌지 않으면서 포워딩 되기 때문에 포워딩 받는 곳에서 필요한 데이터가 노출될 일이 없음
또한 전달하고 싶은 모든 형태의 데이터를 다 전달할 수 있음
여기서는 RequestDispatcher 를 사용해 포워딩 받는 곳에서 데이터를 전달 하는 방법과 포워딩 받는 곳에서 전달 받은 데이터를 꺼내는 방법을 배워보자
굉장히 간단함
앞서 만들었던 forwarding_1과 forwarding_2 서블릿을 활용하자
package chapter04;
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("/chapter04/forwarding_1")
public class Forwarding1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Forwarding1 서블릿의 doGet 메서드 호출됨");
RequestDispatcher rd = request.getRequestDispatcher("/chapter04/forwarding_2");
rd.forward(request, response);
}
}
package chapter04;
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("/chapter04/forwarding_2")
public class Forwarding2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Forwarding2 서블릿의 doGet 메서드 호출됨");
}
}
여기서 주목해야할 부분은 포워딩을 하는 시점임
<< 포워딩을 하는 곳 ( Forwarding1 서블릿 ) >>
포워딩을 하는 시점(1) 에 보면 요청 정보(HttpServletRequest)와 응답 정보(HttpServletResponse) 를 담아서 포워딩을 하고 있는 것
그래서 포워딩을 하는 곳에서 포워딩을 받는 곳으로 데이터를 전달하고 싶을 때는 요청 정보 안에 데이터를 담아서 전달함
요청 정보에 데이터를 담을 때는 setAttribute 메서드를 사용함(1)
setAttribute 메서드의 형식과 설명을 읽어보면 첫 번째 인자는 저장할 데이터의 이름이고 두 번째 인자는 저장할 데이터임
우리가 request.setAttribute("message", "전달하는 데이터") 코드를 썼으므로 요청 정보 안에 [ message=전달하는 데이터 ] 형식으로 데이터가 저장되고 포워딩을 받는 곳에서 이름(message) 을 사용해서 데이터(전달하는 데이터) 를 꺼내서 쓸 수 있음
! 여기서 주의해야할 점 ! 데이터를 저장하기 위해서 setAttribute 메서드를 사용했다는 점
또 ! 주의해야할 점 ! 저장하는 데이터의 타입이 Object 인 점에 주목하자
우리가 뭘 저장하던 요청 정보 안에 저장될 때는 Object 타입으로 형변환 되서 저장됨
( Forwarding1 서블릿에 위와 같이 data1, data2, data3 도 저장하는 코드를 추가하자 )
이번에는 포워딩을 받는 곳에서 전달 받은 데이터를 꺼내보자
포워딩을 받는 곳(Forwarding2 서블릿)에서 전달 받은 데이터를 꺼낼 때는 getAttribute 메서드를 사용함(1)
특히나 꺼낼 때 getAttribute 메서드를 사용해서 꺼낸다. 이외에도 데이터가 저장될 때 원래 형태에서 Object 로 변환되 저장되었으므로 꺼낼 때도 꺼낸 후에 형변환을 통해서 원래 형태로 복원 시켜줘야함
이번에는 여러분이 먼저 data1, data2, data3 을 꺼내서 출력해보자
이제 Forwarding1 서블릿으로 요청을 보내는 웹 페이지를 만들고 요청을 보내 Forwarding2 에서 message부터 data3까지 출력되는걸 확인하자
webapp -> chapter04 -> request.html 페이지를 추가하고 아래 코드를 추가하자
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>RequestDispatcher 방식 포워딩</title>
</head>
<body>
<a href="/studyProject/chapter04/forwarding_1">서버로 요청을 보냄</a>
</body>
</html>
이제 서버를 실행시키고 웹 페이지에 접근해 [ 서버로 요청을 보냄 ] 을 클릭하자
문자열을 전달할 수 있으니 데이터들(배열)이나 정보(객체)도 당연히 전달할 수 있음
객체를 생성하기 위해 chapter04 -> Person 클래스를 추가 하고 아래 코드를 넣자
package chapter04;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
// getter & setter 생략
}
Fowarding1 서블릿 코드를 아래와 같이 바꾸자
package chapter04;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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("/chapter04/forwarding_1")
public class Forwarding1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Forwarding1 서블릿의 doGet 메서드 호출됨");
// request.setAttribute("message", "전달하는 데이터");
// request.setAttribute("data1", 1);
// request.setAttribute("data2", 3.14);
// request.setAttribute("data3", 'a');
int[] array = {1, 2, 3};
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Person p = new Person("홍길동", 21);
request.setAttribute("array", array);
request.setAttribute("list", list);
request.setAttribute("person", p);
RequestDispatcher rd = request.getRequestDispatcher("/chapter04/forwarding_2");
rd.forward(request, response);
}
}
Forwarding2 서블릿을 아래와 같이 바꾸자
package chapter04;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
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("/chapter04/forwarding_2")
public class Forwarding2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Forwarding2 서블릿의 doGet 메서드 호출됨");
// String message = (String) request.getAttribute("message");
// int data1 = (int) request.getAttribute("data1");
// double data2 = (double) request.getAttribute("data2");
// char data3 = (char) request.getAttribute("data3");
//
// System.out.println("message => " + message);
// System.out.println("data1 => " + data1);
// System.out.println("data2 => " + data2);
// System.out.println("data3 => " + data3);
int[] array = (int[]) request.getAttribute("array");
List<Integer> list = (List<Integer>) request.getAttribute("list");
Person p = (Person) request.getAttribute("person");
System.out.println(Arrays.toString(array));
System.out.println(list);
System.out.println(p);
}
}
서버를 재시작하고 [ 서버로 요청을 보냄 ] 을 클릭해보자
지금까지 포워딩을 할 때 데이터를 전달하는 방법을 배웠음
여기서 특징은 포워딩을 서블릿에서 서블릿으로 했음
포워딩은 서블릿에서 HTML 또는 서블릿에서 서블릿 또는 서블릿에서 JSP 로 할 수 있다고 했음
서블릿에서 HTML 로 포워딩할 때 HTML로 데이터를 전달할 수 있을까? 없음
HTML은 보여주기만 가능한 언어이기 때문에 서블릿에서 HTML로 데이터를 전달할 순 없음
서블릿에서 JSP 로 포워딩할 때 JSP로 데이터를 전달할 수 있을까? 있음
그러나 아직 우리가 JSP를 배우지 않았기 때문에 나중에 JSP를 할 때 배울 것
'Servlet + JSP > Serlvet-Chapter04' 카테고리의 다른 글
Chapter04. ServletConfig (0) | 2023.03.03 |
---|---|
Chapter04. ServletContext (0) | 2023.03.03 |
Chapter04. 포워딩(Forwarding) / 클라이언트 몰래 요청 넘기기 (2) | 2023.03.03 |
Chapter04. 포워딩(Forwarding) / 클라이언트에게 "여기로 가!" 지시하기 (0) | 2023.03.02 |
Chapter04. 클라이언트에게 JSON 데이터 전달하기 (0) | 2023.03.02 |