[JSP]객체범위(Scope)
in JSP
객체범위(Scope)
객체 범위 종류
웹 애플리케이션에는 4개의 객체 영역이 존재합니다.
( Application 영역 / Session 영역 / request 영역/ Page 영역 )
1) application 영역
하나의 애플리케이션 당 1개의 application 객체가 생성됩니다.
즉 같은 애플리케이션 내에서 요청되는 페이지들은 같은 객체를 공유하게 되는데 이를 애플리케이션 영역이라고 합니다.
(모든 Servlet, JSP에서 공유하는 영역)
애플리케이션이 종료되면 반환 (웹 서버가 종료될 때 까지 값이 유지된다.)
request.getServletContext() 메서드를 호출하여 애플리케이션 영역에서 유효한 객체를 얻을 수 있습니다.
2) session 영역
하나의 브라우저 당 1개의 session 객체가 생성됩니다.
즉 같은 브라우저 내에서 요청되는 페이지들은 같은 객체를 공유하게 되는데 이를 세션 영역이라고 합니다. 세션이 종료되면 반환됩니다. (웹 브라우져가 종료될 때 또는 세션유지시간 동안 값이 유지된다.) requset.getSession() 메서드를 호출하여 세션 영역에서 유효한 객체를 얻을 수 있습니다.
3) request 영역
요청을 받아서 응답하기까지 객체가 유효한 영역입니다. (클라이언트에 응답할 때 까지)
forward 또는 include를 사용하면 request 기본 객체가 공유되어서 request 영역이 됩니다.
지금까지 Servlet에서 JSP로 객체를 보낼 때 사용했던 방법입니다.
Servlet에서는 reqeust.setAttribute(“이름”, 객체); 로 전달하였고, (scope에 값 저장하기)
JSP에서는 Obejct obj = request.getAttribute(“이름”); 으로 받았습니다.(scope에 값 꺼내오기)
이 때 사용했던 request 객체가 request 영역입니다.
4) page 영역
한 번의 브라우저 요청이 오면 하나의 JSP 페이지가 호출됩니다.
이 때 하나의 JSP 페이지 내에서만 객체를 공유하는 영역을 의미합니다 ( JSP only )
JSP 파일에는 pageContext가 내장되어 있으며, 이 객체는 page 영역에서만 유효합니다.
JSP 파일에 <% %> 안에 변수를 사용하면 이 변수는 해당 JSP 파일 내에서만 유효합니다.
테스트
4개의 scope 개념에 대해 알았으니, 이제 어떻게 활용하는지 알아보도록 하겠습니다.
ScopeServlet.java
@WebServlet("/scope")
public class ScopeSerlvet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// page는 JSP파일에서 작성 ( JSP only )
// request
request.setAttribute("num2", 20);
// session
request.getSession().setAttribute("num3", 30);
// application
request.getServletContext().setAttribute("num4", 40);
RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/index.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
각 영역에 객체를 할당하는 방법은 위와 같습니다.
page 영역은 JSP 내에서만 존재하므로 Servlet에서 만들 수 없습니다.
이제 JSP 파일을 만들어서 각 영역의 값을 확인해보겠습니다.
/WEB-INF/index.jsp
<%
pageContext.setAttribute("num1", 10);
%>
<%@ 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>
${ pageScope.num1 } <br>
${ requestScope.num2 } <br>
${ sessionScope.num3 } <br>
${ applicationScope.num4 } <br>
<hr>
${ num1 } <br>
${ num2 } <br>
${ num3 } <br>
${ num4 } <br>
</body>
</html>
Scope를 출력하는 방법은 위와 같습니다.
- 지금까지 java 코드 값을 출력하는 방식으로 <%= %>을 사용했었는데, 지금은 ${ }을 사용했습니다.
- ${ }은 표현식으로서, 지금은 각 Scope의 값을 출력하는 방법에 주목해주세요.
첫 번째 방법은 Scope 영역을 명시하고 출력하고자 하는 애트리뷰트 명을 작성했고,
두 번째 방법은 바로 애트리뷰트 명을 작성했습니다.
결과를 보면 다음과 같습니다.
두 방법 모두 같은 결과를 얻습니다.
즉, 애트리뷰트 명을 잘 작성했다면 두 번째 방법으로 사용하는 것이 간단하므로 좋을 것입니다.
그런데 서로 다른 영역에 같은 이름을 갖는 애트리뷰트가 있다면 어떤 영역의 애트리뷰트가 선택될까요?
스코프 범위에 따라, 애트리뷰트 명은 좁은 범위의 영역부터 큰 범위의 영역으로 탐색을 합니다.
즉, page -> request -> session -> application 순으로 탐색을 하며, 탐색이 된다면 더 이상 큰 범위로 탐색을 진행하지 않습니다.
스코프에 값 저장하기
xxx.setAttribute(“이름”,저장값);
스코프에 저장된 값 꺼내오기
Object xx.getAttribute(“이름”);
ex) String 형으로 받아오는경우 String val1 = (String)xx.getAttribute(“이름”); 과 같이 형변환 시켜줘야합니다.