내장 객체란?
웹은 클라이언트가 서버로 요청을 보내면, 서버는 맞는 결과를 응답으로 돌려주는 형태로 동작합니다.
이때 JSP의 내장 객체는 요청과 응답 혹은 HTTP 헤더 등의 정보를 쉽게 다룰 수 있도록 해줍니다.
내장 객체는 JSP 페이지가 실행될 때 컨테이너가 자동으로 생성해줍니다.
내장 객체는 다음과 같은 특징을 가지고 있습니다
- 컨테이너가 미리 선언해놓은 참조 변수를 이용해 사용합니다.
- 별도의 객체 생성 없이 각 내장 객체의 메서드를 사용할 수 있습니다.
- JSP 문서 안의 <% 스크립틀릿 %> 과 <%= 표현식 %>에서만 사용할 수 있습니다.
- <%! 선언부 %>에서는 즉시 사용하는 건 불가능하고, 매개변수로 전달받아 사용할 수는 있습니다.
내장 객체는 총 아홉가지가 있습니다.
내장 객체 | 타입 | 설명 |
request | javax.servlet.http.HttpServletRequest | 클라이언트의 요청 정보를 저장합니다. |
response | javax.servlet.http.HttpServletResponse | 클라리언트의 요청에 대한 응답 정보를 저장합니다. |
out | javax.servlet.jsp.JSPWriter | JSP 페이지에 출력할 내용을 담는 출력 스트림입니다. |
session | javax.servlet.http.HttpSession | 웹 브라우저 정보를 유지하기 위한 세션 정보를 저장합니다. |
application | javax.servlet.ServletContext | 웹 애플리케이션 관련 컨텍스트 정보를 저장합니다. |
pageContext | javax.servlet.jsp.PageContext | JSP 페이지에 대한 정보를 저장합니다. |
page | java.lang.Object | JSP 페이지를 구현한 자바 클래스의 인스턴스입니다. |
config | javax.servlet.ServletConfig | JSP 페이지에 대한 설정 정보를 저장합니다. |
exception | java.lang.Throwable | 예외가 발생한 경우에 사용합니다. |
request 객체
request 내장 객체는 JSP에서 가장 많이 사용되는 객체로, 클라이언트(주로 웹 브라우저)가 전송한 요청 정보를 담고 있는 객체입니다.
전송한 정보는
데이터 전송 방식은 GET, POST 요청이 있으며, request 객체의 주요 기능은 다음과 같습니다.
- 클라이언트와 서버에 대한 정보 읽기
- 클라이언트가 전송한 요청 매개변수에 대한 정보 읽기
- 요청 헤더 및 쿠키 정보 읽기
response 객체
requests 내장 객체가 클라이언트의 요청 정보를 저장하는 역할을 했다면, response 내장 객체는 그와 반대로 요청에 대한 응답을 웹브라우저로 보내주는 역할을 합니다.
주요기능으로는 페이지 이동을 위한 리다이렉트(redirect)와 HTTP 헤더에 응답 헤더 추가 등이 있습니다.
out 객체
out 내장 객체는 웹 브라우저에 변수 등의 값을 출력할 때 주로 사용합니다. 하지만 JSP를 작성하면서 사용하는 일은 많지 않습니다.
대부분의 상황에서는 <%= %> 이 더 편리하기 때문입니다.
하지만 스크리틀릿 내에서 변수를 웹 브라우저에 출력해야 한다면 표현식보다는 out 내장 객체를 사용하는 편이 좋습니다.
out 내장 객체는 버퍼를 사용합니다.
application 객체
application 객체는 웹 애플리케이션당 하나만 생성되며, 모든 JSP 페이지에서 접근할 수 있습니다
주로 웹 애플리케이션 전반에서 이용하는 정보를 저장하거나, 서버의 정보, 서버의 물리적 경로 등을 얻어오는데 사용합니다.
web.xml은 웹 애플리케이션에 대한 여려 가지 설정을 저장하는 곳으로, 배포 서술자라고 부릅니다.
물리적 경로란 특정 파일이나 폴더 전체 경로, 즉 절대 경로를 말하며, 파일을 업로드하거나 입출력 작업 시에 주로 사용합니다.
exception 객체
exception 내장 객체는 오류명과 오류 메시지를 출력하는 부분에서 사용되고 있습니다.
내장 객체의 영역
영역은 각 객체가 저장되는 메모리의 유효기간입니다.
내장 객체의 영역은 총 4가지가 있습니다.
- page 영역 : 동일한 페이지에서만 공유됩니다. 페이지를 벗어나면 소멸됩니다.
- request 영역 : 하나의 요청에 의해 호출된 페이지와 포워드(요청 전달)된 페이지까지 공유됩니다.
- session 영역 : 클라이언트가 처음 접속한 후 웹브라우저를 닫을 때까지 공유됩니다.
- application 영역 : 한 번 저장되면 웹 애플리케이션이 종료될 때까지 유지됩니다.
데이터 전송 객체(DTO)
데이터 전송 객체(DTO)란 주로 데이터를 저장하거나 전송하는데 쓰이는 객체로 다른 로직 없이 순수하게 데이터만을 담고 있습니다.
DTO는 JSP파일이 아닌 일반적인 자바 클래스입니다. 즉 Java Resources 하위의 src에 생성합니다.
DTO는 자바빈즈 규약에 따라 작성합니다.
자바 빈즈란 자바로 작성한 소프트웨어 컴포넌트로, 규약이 존재합니다.
자바빈즈 규약
- 자바빈즈는 기본(default) 패키지 이외의 패키지에 속해야 합니다.
- 멤버 변수(속성)의 접근 지정자는 private으로 선언합니다.
- 기본 생성자가 있어야 합니다.
- 멤버 변수에 접근할 수 있는 게터(getter) / 세터(setter)메서드가 있어야 합니다.
- 게터 / 세터 메서드의 접근 지정자는 public으로 선언합니다.
package basic; // 기본 패키지 이외의 패키지(규약 1번)
public class Person {
private String name; // private 멤버 변수(규약 2번)
private int age; // private 멤버 변수(규약 2번)
public Person() {} // 기본 생성자(규약 3번)
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
// public 게터/세터 메서드들(규약 4번, 5번)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
내장 객체 영역별 수명 주기
page 영역
page 영역은 기본적으로 클라이언트의 요청을 처리하는데 관여하는 JSP 페이지마다 하나씩 생성됩니다.
그리고 이때 각 JSP 페이지는 page 영역을 사용하기 위한 pageContext 객체를 할당 받게 됩니다.
pageContext는 내장 객체 중 하나로 이 객체에 저장된 정보는 해당 페이지에서만 사용 가능합니다.include 지시어로 포함된 파일은 하나의 페이지로 통합되므로 page 영역이 공유됩니다.
다음 예제는 해당 페이지에 속성 값을 저장하고 다른 JSP파일을 include하여 포함된 파일에서 속성을 불러오는 예제입니다.
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 속성 저장
pageContext.setAttribute("pageInteger", 1000);
pageContext.setAttribute("pageString", "페이지 영역의 문자열");
pageContext.setAttribute("pagePerson", new Person("한석봉", 99));
%>
<html>
<head><title>page 영역</title></head>
<body>
<h2>page 영역의 속성값 읽기</h2>
<%
// 속성 읽기
int pInteger = (Integer)(pageContext.getAttribute("pageInteger"));
String pString = pageContext.getAttribute("pageString").toString();
Person pPerson = (Person)(pageContext.getAttribute("pagePerson"));
%>
<ul>
<li>Integer 객체 : <%= pInteger %></li>
<li>String 객체 : <%= pString %></li>
<li>Person 객체 : <%= pPerson.getName() %>, <%= pPerson.getAge() %></li>
</ul>
<h2>include된 파일에서 page 영역 읽어오기</h2>
<%@ include file="PageInclude.jsp" %>
<h2>페이지 이동 후 page 영역 읽어오기</h2>
<a href="PageLocation.jsp">PageLocation.jsp 바로가기</a>
</body>
</html>
PageInclude.jsp 파일
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h4>Include 페이지</h4>
<%
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>
<li>Person 객체 : <%= pPerson2.getName() %>, <%= pPerson2.getAge() %></li>
</ul>
이동 후 페이지에서는 속성값을 불러 올 수 없는 것을 알 수 있습니다.
request 영역
클라이언트가 요청 할 때마다 새로운 request 객체가 생성되고, 같은 요청을 처리하는데 사용되는 모든 JSP가 페이지가 공유합니다.
request 영역에 저장된 정보는 현재 페이지와 포워드된 페이지까지 공유할 수 있습니다.
하지만 페이지 이동 시에는 소멸되어 사용할 수 없습니다.
다음 예제는 포워드 시 속성 값을 계속 가져가는지 확인하는 예제입니다.
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setAttribute("requestString", "request 영역의 문자열");
request.setAttribute("requestPerson", new Person("안중근", 31));
%>
<html>
<head><title>request 영역</title></head>
<body>
<h2>request 영역의 속성값 삭제하기</h2>
<%
request.removeAttribute("requestString");
request.removeAttribute("requestInteger"); // 없는 속성을 삭제해도 에러 없음
%>
<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>
<%
request.getRequestDispatcher("RequestForward.jsp?paramHan=한글¶mEng=English") // 5
.forward(request, response); // 포워드 실행
%>
</body>
</html>
RequestForward.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"));
%>
<ul>
<li>String 객체 : <%= request.getAttribute("requestString") %></li>
<li>Person 객체 : <%= pPerson.getName() %>, <%= pPerson.getAge() %></li>
</ul>
<h4>매개변수로 전달된 값 출력하기</h4>
<%
request.setCharacterEncoding("UTF-8"); //매개변수로 전달된 값 중 한글이 포함되어 있기 때문에 utf-8로 변경
out.println(request.getParameter("paramHan"));
out.println(request.getParameter("paramEng"));
%>
</body>
</html>
포워드를 해도 request 영역이 공유되므로 속성이 잘 전달된 것을 알 수 있습니다.
session 영역
클라이언트가 웹 브라우저를 최초로 열고난 후 닫을 때 까지 요청되는 모든 페이지는 session 객체를 공유할 수 있습니다.
세션(session)이란 클라이언트가 서버에 접속해 있는 상태를 말하는 것으로, 로그인 상태를 유지하는 처리에 사용됩니다.
다음 예제는 session 영역의 특성이 잘 반영되는지 확인하는 예제입니다.
<%@ page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
ArrayList<String> lists = new ArrayList<String>();
lists.add("리스트");
lists.add("컬렉션");
session.setAttribute("lists", lists);
%>
<html>
<head><title>session 영역</title></head>
<body>
<h2>페이지 이동 후 session 영역의 속성 읽기</h2>
<a href="SessionLocation.jsp">SessionLocation.jsp 바로가기</a>
</body>
</html>
SessionLocation.jsp 파일
<%@ page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head><title>session 영역</title></head>
<body>
<h2>페이지 이동 후 session 영역의 속성 읽기</h2>
<%
ArrayList<String> lists = (ArrayList<String>)session.getAttribute("lists");
for (String str : lists)
out.print(str + "<br/>");
%>
</body>
</html>
페이지 이동 후
페이지가 이동후 값이 그대로 남아 있는걸 확인할 수 있습니다.
브라우저의 탭을 닫고 SessionLocation.jsp파일을 다시 실행 시켜도 오류 코드 500이 나오지 않고 화면이 잘 나옵니다.
하지만 브라우저 자체를 종료하고 SessionLocation.jsp 파일을 실행 시킬 시 오류 코드 500이 나오게 됩니다.
application 영역
웹 애플리케이션은 단 하나의 application 객체만 생성하고, 클라이언트가 요청하는 모든 페이지가 application 객체를 공유하게 됩니다.
또한 웹 서버를 시작할 때 만들어지며, 웹 서버를 내릴 때 삭제됩니다. 따라서 application 영역에 한 번 저장된 정보는 페이지를 이동하거나, 웹 브라우저를 닫았다가 새롭게 접속해도 삭제되지 않습니다.
아래 예제는 application 영역을 통해 브라우저를 껐다 켜도 다시 실행되는지 확인하는 예제입니다.
<%@ page import="java.util.HashMap"%>
<%@ page import="common.Person"%>
<%@ page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head><title>application 영역</title></head>
<body>
<h2>application 영역의 공유</h2>
<%
Map<String, Person> maps = new HashMap<>();
maps.put("actor1", new Person("이수일", 30));
maps.put("actor2", new Person("심순애", 28));
application.setAttribute("maps", maps); <!--해쉬 맵을 통해 두 객체를 저장하고 application에 저장-->
%>
application 영역에 속성이 저장되었습니다.
</body>
</html>
ApplicationResult.jsp 파일
<%@ page import="java.util.Set"%>
<%@ page import="common.Person"%>
<%@ page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head><title>application 영역</title></head>
<body>
<h2>application 영역의 속성 읽기</h2>
<%
Map<String, Person> maps
= (Map<String, Person>)application.getAttribute("maps");
Set<String> keys = maps.keySet();
for (String key : keys) {
Person person = maps.get(key);
out.print(String.format("이름 : %s, 나이 : %d<br/>",
person.getName(), person.getAge()));
}
%>
</body>
</html>
이 예제를 session 영역을 삭제했을 때 처럼 브라우저 전체를 닫고 다시 실행시켜도 속성 값이 여전히 존재하여 출력됩니다.
4가지 영역 모두 사용방법은 같지만 공유 범위는 서로 다름으로, 알맞게 활용하는 것이 좋다.
'Web' 카테고리의 다른 글
Mac m1에서 자바 버전 변경하기(brew 사용) (2) | 2023.10.17 |
---|---|
세션(Session) with JSP (0) | 2023.08.18 |
쿠키(Cookie) with JSP (0) | 2023.06.21 |
JSP 동작과 기본구조 및 용어 (0) | 2023.06.20 |