자바(JAVA)/JSP 웹 프로그래밍 공부 (성낙현의 JSP 자바 웹 프로그래밍 참고)

JAVA/JSP 8. 내장 객체의 영역(Scope) - page 영역, request 영역

개발학생 2023. 4. 30. 18:25
반응형

1. page 영역

  • 클라이언트의 요청을 처리하는 데 관여하는 JSP 페이지마다 하나씩 생성됨
  • 각 JSP 페이지는 page 영역을 사용하기 위한 pageContext 객체(내장 객체 중 하나)를 할당 받게 됨 → pageContext 객체에 저장된 정보는 해당 페이지에서만 사용 가능(해당 페이지를 벗어나면 소멸됨) → 단, include 지시어로 포함한 파일은 하나의 페이지로 통합되므로, page 영역 공유 가능

 

* include 된 파일에서 page 영역 읽어오기, 페이지 이동 후 page 영역 읽어오기

(1) page 영역에 값을 저장하고 불러오는 예

//PageContextMain.jsp
<%@ page import="common.Person"%>    // 1.common.Person 임포트
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
// 2.속성 저장(아래 3줄의 코드)
pageContext.setAttribute("pageInteger", 1000);
pageContext.setAttribute("pageString", "페이지 영역의 문자열");
pageContext.setAttribute("pagePerson", new Person("한석봉", 99)); 
%>
<html>
<head><title>page 영역</title></head>
<body>
    <h2>page 영역의 속성값 읽기</h2>
    <%
    // 3.속성 읽기(아래 3줄의 코드)
    int pInteger = (Integer)(pageContext.getAttribute("pageInteger"));
    String pString = pageContext.getAttribute("pageString").toString();    // 4.String타입
    Person pPerson = (Person)(pageContext.getAttribute("pagePerson"));
    %>
    <ul>
        <li>Integer 객체 : <%= pInteger %></li>
        <li>String 객체 : <%= pString %></li>
        <li>Person 객체 : <%= pPerson.getName() %>, <%= pPerson.getAge() %></li>    // 5.
    </ul>

    <h2>include된 파일에서 page 영역 읽어오기</h2>
    <%@ include file="PageInclude.jsp" %>    // 6.
       
    <h2>페이지 이동 후 page 영역 읽어오기</h2>
    <a href="PageLocation.jsp">PageLocation.jsp 바로가기</a>    // 7.
</body>
</html>
  1. 이 파일에서 외부 클래스인 common.Person을 사용하기 위해 import
  2. pageContext 객체를 통해 page 영역에 속성값 저장.
    객체가 아닌 기본 타입 값들은 해당 래퍼(wrapper) 클래스로 오토박싱(auto boxing)된 후 저장됨
    [int는 Integer로, float는 Float로, ...]
  3. 2.에서 저장한 속성들을 다시 읽어옴(모든 속성이 Object 타입으로 저장되어 있으므로 다시 원래 타입으로 형변환)
  4. String 타입인 경우 toString() 메소드를 통해 문자열로 변환하여 출력할 수도 있음
  5. Person 객체에서 멤버 변수의 값을 읽어오는 예
    (Person은 DTO라서 멤버 변수가 private로 선언되었으므로 Getter 메소드 사용)
  6. include 지시어로 다른 JSP 파일 포함시킴(포함 관계이므로 ‘같은 페이지’가 됨→page 영역 그대로 유지됨)
  7. <a>로 감싼 링크를 클릭하면 ‘다른 페이지’로 이동함(이전 페이지에서 만든 page 영역 소멸)
// 위의 PageContextMain.jsp의 6.에서 include 지시어로 포함시킨 파일
// PageInclude.jsp
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h4>Include 페이지</h4>
<%
// 아래 코드 3줄 - 1.속성 읽기
int pInteger2 = (Integer)(pageContext.getAttribute("pageInteger"));
//String pString2 = pageContext.getAttribute("pageString").toString();
Person pPerson2 = (Person)(pageContext.getAttribute("pagePerson"));
%>
<ul>
    <li>Integer 객체 : <%= pInteger2 %></li>
    <li>String 객체 : <%= pageContext.getAttribute("pageString") %></li>    // 2.
    <li>Person 객체 : <%= pPerson2.getName() %>, <%= pPerson2.getAge() %></li>
</ul>
  1. page 영역에 저장된 속성을 읽어와서 형변환 함(String 객체는 주석으로 처리)
  2. String 객체를 직접 출력
    (저장한 객체가 문자열이거나 기본 타입의 wrapper 클래스라면, 별도의 형변환 없이 출력해도 됨)
  • PageContextMain.jsp를 실행해 보면, PageInclude.jsp가 출력한 내용이 그대로 출력된다.

 

(2) page 영역 공유가 불가능한 예

// PageLocation.jsp(PageContextMain.jsp의 <a> 태그 링크 영역>
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head><title>page 영역</title></head>
<body>
    <h2>이동 후 page 영역의 속성값 읽기</h2>
    <%
		//1.속성 읽기(아래 코드 3줄) 
    Object pInteger = pageContext.getAttribute("pageInteger");
    Object pString = pageContext.getAttribute("pageString");
    Object pPerson = pageContext.getAttribute("pagePerson"); 
    %>
    <ul>
				//2.(아래 코드 3줄)
        <li>Integer 객체 : <%= (pInteger == null) ? "값 없음" : pInteger %></li>
        <li>String 객체 : <%= (pString == null) ? "값 없음" : pString %></li>
        <li>Person 객체 : <%= (pPerson == null) ? "값 없음" : ((Person)pPerson).getName() %></li>
    </ul>
</body>
</html>
  1. page 영역에서 ‘형변환 없이’ 속성값을 가져옴
    (가져오려는 속성이 존재하지 않으면 getAttribute() 메소드가 null을 반환하는데,
    null을 int 타입 변수에 담으려 하면 NullPointerException 발생)
  2. 값을 화면에 출력할 때 null이 아닌지 확인
  • PageContextMain.jsp에서 왼쪽 사진처럼 밑줄 친 부분을 클릭하면 PageLocation.jsp로 이동하는데, 오른쪽 사진처럼 모든 값의 자리에 ‘값 없음’을 출력함

 

2. request 영역

  • 클라이언트가 요청을 할 때마다 새로운 request 객체가 생성됨
  • 같은 요청을 처리하는 데 사용되는 모든 JSP 페이지가 공유 →request 영역에 저장된 정보는 현재 페이지와 포워드 된 페이지까지 공유할 수 있음(단, 페이지 이동 시 소멸되어 사용 불가)
  • 하나의 요청에 대한 응답이 완료될 때 소멸하게 되므로, page 영역보다 접근 범위가 좀 더 넓음

* request 영역 동작 확인, 포워드 된 후에도 request 영역이 공유되는지 확인

// RequestForward.jsp
// 포워드되는 JSP 페이지
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head><title>request 영역</title></head>
<body>
    <h2>포워드로 전달된 페이지</h2>
    <h4>RequestMain 파일의 리퀘스트 영역 속성 읽기</h4>
    <%  
    Person pPerson = (Person)(request.getAttribute("requestPerson"));    //1.
    %>
    <ul>
        <li>String 객체 : <%= request.getAttribute("requestString") %></li>
        <li>Person 객체 : <%= pPerson.getName() %>, <%= pPerson.getAge() %></li>    //2.
    </ul>
    <h4>매개변수로 전달된 값 출력하기</h4>
    <%
        request.setCharacterEncoding("UTF-8");    //3.
				//4.(아래 2줄)
        out.println(request.getParameter("paramHan"));
        out.println(request.getParameter("paramEng"));
    %>
</body>
</html>

1./2. request 영역에 저장된 속성들을 읽어와서 출력(여기서 불러오는 속성들은 아래의 RequestMain.jsp에서 저장한 것들) → 포워드를 해도 request 영역이 공유되므로, 문제없이 출력될 것

3. 인코딩 방식을 UTF-8로 변경(매개변수로 포함된 값 중 한글이 포함되어 있기 때문)

4. 포워드하면서 쿼리스트링으로 전달할 매개변수의 값을 출력. (값을 읽어오기 전에 3.실행하고 출력)

// RequestMain.jsp
// request 영역 동작 확인용 페이지(문제없이 잘 동작함)
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
//1. 속성 저장(아래 코드 2줄)
request.setAttribute("requestString", "request 영역의 문자열");
request.setAttribute("requestPerson", new Person("안중근", 31)); 
%>
<html>
<head><title>request 영역</title></head>
<body>
    <h2>request 영역의 속성값 삭제하기</h2>
    <%
        request.removeAttribute("requestString");    //2.
        request.removeAttribute("requestInteger");    //3. 에러 없음
    %>
		//4.(</ul> 부분까지-7줄)
    <h2>request 영역의 속성값 읽기</h2>
    <%
    Person rPerson = (Person)(request.getAttribute("requestPerson"));
    %>
    <ul>
        <li>String 객체 : <%= request.getAttribute("requestString") %></li>
        <li>Person 객체 : <%= rPerson.getName() %>, <%= rPerson.getAge() %></li>
    </ul>
    <h2>포워드된 페이지에서 request 영역 속성값 읽기</h2>
	  //5.(%> 부분까지-4줄, 주석처리)
    <%--
    request.getRequestDispatcher("RequestForward.jsp?paramHan=한글&paramEng=English")  
        .forward(request, response);    //6.
    --%>
</body>
</html>

1. request 영역에 String 객체와 Person 객체 저장

2./ 3. request 영역에 저장된 속성 삭제

4. request 영역에 저장된 속성값을 읽어온 후 출력

5. 핵심! RequestForward.jsp로 포워드하는 코드. 우선 주석처리 상태로 실행

6. request 내장 객체를 통해 실제로 포워드를 수행하는 코드

request.getRequestDispatcher("포워드할 파일 경로").forward(request,response)

 

(1) RequestMain.jsp의 5.부분 주석 처리 시

  • 문제없이 잘 동작함을 알 수 있음

 

(2) RequestMain.jsp의 5.부분 주석 처리 해제 시

  • 최초 페이지(RequestForward.jsp)에서 request 영역에 저장했던 값을 성공적으로 불러옴 → 웹 브라우저의 주소 표시줄에는 여전히 최초 실행한 RequestMain.jsp가 표시되지만, 화면에는 RequestForward.jsp의 내용 ‘한글 English’도 확인됨
    • String 객체가 여전히 null로 출력되는 이유는, 최초 실행한 페이지에서 removeAttribute() 메소드로 삭제했기 때문. Person 객체에 매개변수로 전달한 값들은 문제없이 출력됨

  •  
반응형