8. 유효 범위(scope)와 속성(attribute)
HTTP 특징 중에 상태 정보를 저장하지 않는다는 것을 'stateless'라 하고 반대되는 개념은 'stateful'이라 한다. 'stateful'은 상태 정보를 저장한다는 뜻이된다. HTTP의 'stateless'특징 때문에 저장소가 필요하고 유효 범위(scope)에 따라 4개가 있다. 4개의 저장소를 구분 짓는 특징은 접근 범위, 생존 기간이 있다. 접근 범위와 생존 기간이 다른 4개의 저장소가 있다.
저장소는 Map의 형태로 data를 저장한다.
저장소 1. pageContext
pageContext안에 Map이 있다. 이 저장소는 lv 지역변수를 저장한다. 기본 객체(request, response)가 lv이기 때문에 pageContext안에 들어있다. 범위는 page이고 page안에 있는 코드만 접근할 수 있다. 프로그래밍에서 접근은 읽고 쓰기가 된다는 뜻이다. 정확히는 Map을 읽고 쓴다.
같은 메서드 안에 있는데 lv를 굳이 저장해야 할까 하는 의문이 들 수 있다. EL때문에 lv를 저장해야 한다. jsp에서 값 찍을 때 <%=lv%>는 된다. 하지만 EL은 ${lv}가 안된다. EL로는 lv에 직접 접근할 수 없다. EL에서 쓰려면 pageContext에 저장하고 그 다음에 EL에서 lv를 읽을 수 있다. 이렇게 쓰는 이유는 <%=lv%>가 불편해서 EL인 ${lv}로 개선했는데 저장소가 필요했고 이 저장소가 pageContext이다.
같은 page안이지만 pageContext 저장소를 사용해서 값을 읽고 쓴다. 또한 기본 객체를 사용하려면 pageContext를 거쳐서 사용해야 한다. 기본 객체는 lv 지역변수이다. pageContext의 장점은 다른 page의 접근이 불가능하다. 또 요청할 때마다 초기화되어 앞에 사람이 쓰던 값이 남아있는 경우가 없다.
저장소 2. application
접근 범위로는 Web Application 전체에서 접근 가능하다. 딱 1개만 존재한다. 한 pageContext에서는 쓰기, 다른 pageContext에서는 읽기가 가능하다. 저장소에 Map 형태로 data를 저장하는데 data 쓰기(저장)는 setAttribute 메서드, data 읽기는 getAttribute 메서드를 사용한다. 이 두 메서드는 저장소에서 data를 읽고 쓰는 공통 메서드이다.
클라이언트가 첫 요청으로 id, pwd를 입력해서 login하고, 두 번째로 글쓰기 요청을 보내면 이 요청에서는 login 했다는 것을 알 수 없다. 이유는 HTTP는 상태 정보가 없어 두 요청이 같은 클라이언트인지 모른다.
application 저장소의 key값에 id를 저장한다. key가 속성(attribute)이기 때문에 읽고 쓰는 메서드에 Attribute 단어가 들어간다. 하지만 application 저장소는 모든 페이지에서 접근가능하므로 다른 사용자가 login을 하면 value의 기존 정보가 사라진다. application은 전체에서 공유하는 저장소이기 때문에 개별적인 data(id, pwd)를 저장하기에는 좋지 않다.
저장소 3. session
application 저장소의 단점으로 session 저장소가 생겼다. 클라이언트에 있는 개별 저장소이고 클라이언트와 저장소가 1:1 이다. 한 클라이언트의 저장소에 id로 'asdf'가 저장되고 다른 클라이언트의 저장소에는 id로 'aaa'가 저장된다. 따라서 로그인 후에도 로그인 정보가 남아있어 글을 쓸 수 있다. 나중에 쿠키를 배울텐데 session은 쿠키를 이용해서 session이 어느 클라이언트의 저장소인지 연결한다.
session 저장소는 클라이언트에 있는 개별 저장소이다. login하면 개별 저장소가 생기고 logout하면 삭제된다. 저장소에는 id, 장바구니 등 개인정보를 담으면 좋다. 단점은 사용자마다 갖는 개별저장소이기 때문에 사용자 숫자만큼 객체가 생긴다. 최소한의 data만 session 저장소에 저장해야한다. session 저장소가 서버부담이 제일 크다. session 객체는 login하는 동안 여러 저장소가 접근 가능해 프로그래밍하기 쉽지만 서버부담이 크기 때문에 최소한의 data만 저장해야한다.
저장소 4. request
request 객체도 Map을 갖고 있다. 요청할 때마다 생기고 클라이언트에 독립적이다. 요청을 하나의 JSP page가 담당해서 JSP안에서 request 객체를 사용할 수 있다. Map data도 저장할 수 있다.
보통은 요청을 JSP가 응답하면 끝이 나는데 반드시 그런건 아니다. 요청을 첫 번째 JSP가 응답을 하지 않고 다른 JSP에 request 객체를 넘겨줄 수 있다. 이를 forward라 한다. a.jsp를 호출 했는데 request를 처리하지 못할 경우 b.jsp로 request 객체를 넘긴다.
web 프로그래밍이란 page간의 data이동이다. 제일 쉬운 저장소가 session이다. 하지만 메모리 부담이 제일 크다. 다음 제일 많이 사용하는 저장소가 request이다. request를 사용하지 못할 때 session에 잠깐 저장했다가 삭제한다.
pageContext의 범위 : page내(EL ${ } 때문에 사용한다.)
application의 범위 : Servlet Conext 전체(page에서 application에 접근 가능하다. 프로그램 전체에서 공통으로 사용하는 dat를 저장한다.)
session의 범위 : 클라이언트가 접근하는 page 전체(web은 page간의 data전달인데 request에 담아서 전달하는 방법이 일반적이다. 대신 서버의 메모리 부담이 커 사용하고 바로 삭제한다.)
request의 범위 : 요청할 때 request 객체에 담아서 page를 이동하므로 우선적으로 request에 담는다.
setAttribute, getAttribute 둘을 가장 많이 쓴다. setAttribute는 data가 Map 형태로 저장되어 있어 매개 변수로 key, value를 적어야 한다. remove는 session객체의 부담으로 바로 삭제할 때 사용한다.
'스프링의 정석 > Ch. 02 Spring MVC' 카테고리의 다른 글
16. 서블릿과 JSP (4) (0) | 2023.07.19 |
---|---|
15. 서블릿과 JSP (3) (0) | 2023.07.15 |
13. 서블릿과 JSP (1) (0) | 2023.07.09 |
12. 관심사의 분리와 MVC패턴 - 원리(2) -> 다시 듣기 (0) | 2023.07.07 |
11. 관심사의 분리와 MVC패턴 - 원리(1) (0) | 2023.07.06 |