본문 바로가기
WEB/Servlet, JSP

[Servlet] 상태 정보 유지 기술

by Amy IT 2022. 7. 10.

 

목차

     

     

    상태 정보 유지 기술

    웹에서 사용하는 HTTP 프로토콜의 통신 방식은 무상태(Stateless)의 특징을 가집니다. 클라이언트로부터 요청이 있을 때마다 연결 작업이 새롭게 이루어지고, 서버가 클라이언트에게 응답을 보내는 즉시 끊어집니다. 따라서 이전 요청에서 처리된 정보를 계속해서 사용하고 싶다면, 반드시 클라이언트나 서버에 정보를 저장해서 유지해야 합니다. 이처럼 상태 정보(State Information)를 계속된 요청에서 사용할 수 있도록 클라이언트나 서버에 저장하는 것을 상태 정보 유지 기술이라고 합니다. 상태 정보 유지 기술은 다음과 같이 저장 위치, 유지 기간에 따라 분류할 수 있습니다.

     

    객체 상태 정보 저장 위치 유지 기간
    ServletContext 서버 측에 저장 웹 애플리케이션 단위로 유지
    HttpSession 클라이언트 단위로 유지
    HttpServletRequest 클라이언트의 서비스 요청 단위로 유지
    Cookie 클라이언트 측에 저장 클라이언트 단위로 유지

     

     

     

    서버 측에 저장 - 스코프(scope)

    스코프는 필요시 임의의 데이터를 저장하고 나중에 저장된 데이터를 사용할 수 있는 특별한 저장소입니다. request 스코프, session 스코프, application (context) 스코프가 제공되며, request < session < application 순으로 범위가 넓어집니다. 위에서 확인한 HttpServletRequest API가 request 스코프, HttpSession API가 session 스코프, ServletContext API가 application 스코프에 해당합니다. 데이터는 속성(attribute)으로 스코프에 저장 가능하며, name과 value의 쌍으로 저장합니다.

     

    스코프 객체 메소드

    메소드 기능
    void setAttribute(String name, Object value) 스코프 객체에 데이터를 name, value의 쌍으로 저장(등록)한다.
    Object getAttribute(String name) 스코프 객체에 저장된 데이터 중 지정한 name에 해당하는 value를 반환한다.
    void removeAttribute(String name) 스코프 객체에 저장된 데이터 중 지정한 name에 해당하는 데이터를 삭제한다.
    Enumeration getAttributeNames() 스코프 객체에 저장된 데이터의 모든 name 값을 Enumeration 객체에 담아 반환한다.

     

    @WebServlet("/SetScopeServlet")
    public class SetScopeServlet extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//1.request scope에 저장: 요청~응답까지의 라이프사이클
    		request.setAttribute("request", "홍길동"); 
    
    		//2.session scope에 저장: 브라우저의 라이프사이클
    		HttpSession session = request.getSession(); //브라우저의 session id를 가져와 HttpSession 객체 생성 (사용자마다 다름)
    		session.setAttribute("session", "이순신"); 
    		
    		//3.apllication scope에 저장: 웹 어플리케이션에서의 context의 라이프사이클
    		//가장 광범위하게 저장, 모든 서블릿, 모든 사용자 사용가능 
    		ServletContext ctx = getServletContext(); //ServletContext 객체 생성
    		ctx.setAttribute("application", "유관순");
    	}
    }
    @WebServlet("/GetScopeServlet")
    public class GetScopeServlet extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//1.request scope
    		String a = (String) request.getAttribute("request");
    		System.out.println("request scope : "+a);
    	
    		//2.session scope
    		HttpSession session = request.getSession();
    		String b = (String) session.getAttribute("session");
    		System.out.println("session scope : "+b);
    
    		//3.apllication scope
    		ServletContext ctx = getServletContext();
    		String c = (String) ctx.getAttribute("application");
    		System.out.println("application scope : "+c);
    	}
    }

     

    SetScopeServlet을 실행해서 필요한 데이터를 각 스코프 객체에 저장한 후, 서버와 브라우저가 살아있는 상태에서 GetScopeServlet을 실행해 저장된 데이터를 꺼내와 출력하고 있습니다.

     

    request scope

    request scope는 요청에서 응답까지의 라이프 사이클을 가집니다. SetScopeServlet을 실행할 때의 요청과 GetScopeServlet을 실행할 때의 요청은 서로 다른 요청이기 때문에, HttpServletRequest 객체에 저장한 데이터는 GetScopeServlet에서 공유되지 않아 null이 출력되고 있습니다. HttpServletRequest 객체에 저장한 데이터를 유지하고 싶으면 요청을 재지정하는 것이 필요합니다. 자세한 내용은 이 글을 참고하시길 바랍니다.

     

    session scope

    session scope는 브라우저의 라이프 사이클과 동일합니다. HttpSession 객체에 저장한 데이터는 브라우저가 살아있는 동안 서버에 유지됩니다. 따라서 GetScopeServlet에서 데이터를 꺼내와 출력 가능합니다. HttpSession 객체가 생성될 때는 요청을 보내온 클라이언트 정보, 요청 시간 정보 등을 조합한 세션 ID가 부여됩니다. 클라이언트마다 개별적으로 생성되어 브라우저가 살아있는 동안 유지되기 때문에 로그인과 같은 사용자 인증 처리 등에 사용됩니다.

     

    메소드 기능
    request.getSession() 클라이언트가 가지고 있는 세션 ID와 동일한 세션 객체를 찾아서 주소값을 반환한다. 세션이 존재하지 않으면 새로운 HttpSession 객체를 생성하여 반환한다.
    String getId() 생성된 세션 ID 값을 반환한다.
    void setMaxInactiveInterval(int second) 지정된 시간만큼 세션을 유지시킨다.
    int getMaxInactiveInterval() 세션의 유지시간을 반환한다. 기본 유지시간은 30분이다.
    void invalidate() 즉시 세션 영역을 제거한다.

     

    application scope

    application scope는 웹 애플리케이션에서의 context의 라이프 사이클과 동일합니다. 가장 광범위하게 저장되며 모든 서블릿에서 모든 사용자가 저장된 데이터를 사용할 수 있습니다. ServletContext 객체에 저장한 데이터는 웹 애플리케이션 단위로 정보가 유지되기 때문에, 서버가 살아있는 한 새로운 요청이 가도, 브라우저를 종료한 후 다시 열어도 정보가 유지됩니다.

     

     

     

    클라이언트 측에 저장 - 쿠키(Cookie)

    쿠키는 서버가 클라이언트에 저장하는 정보로서 클라이언트 측에 필요한 정보를 저장해놓고 필요할 때 추출하는 것을 지원하는 기술입니다. 클라이언트에 저장된 쿠키 정보는 다시 서버에 방문할 때 자동으로 요청정보의 헤더 안에 포함되어 전달됩니다. 

     

    세션과 쿠키의 차이점

    세션과 쿠키는 클라이언트 단위로 상태정보를 유지한다는 점에서 유사하지만, 다음과 같은 차이점이 있습니다.

     

    구분 세션 쿠키
    저장 위치 서버 클라이언트
    저장 데이터 타입 객체 텍스트
    저장 데이터 크기 서버에서 수용할 수 있는 만큼 제한 있음

     

    쿠키 생성자 및 메소드

     

    생성자 및 메소드 기능
    Cookie(name, value) 쿠키 생성시 사용되는 생성자이다.
    response.addCookie(cookie) 생성된 쿠키를 응답처리 한다.
    request.getCookies() 클라이언트로부터 쿠키 정보를 배열로 리턴받는다.
    setMaxAge(second) 쿠키 만료시간을 설정한다.
    getMaxAge() 쿠키 만료시간을 반환한다.
    getName() 쿠키 이름을 반환한다.
    setValue(value) 쿠키 값을 설정한다.
    getValue() 쿠키 값을 얻는다.
    length 쿠키 개수를 반환한다.

     

    @WebServlet("/SetCookie")
    public class SetCookie extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//1.쿠키 생성
    		Cookie c = new Cookie("username", "홍길동"); //key:value  (Object안됨) 
    		Cookie c1 = new Cookie("age", "20");
    		//2.작업 후 응답에 쿠키 시간 설정 후 추가
    		c.setMaxAge(60*60*24);
    		c1.setMaxAge(60*60*24);
    		response.addCookie(c); //사용자의 로컬에 저장됨  (F12 Application - Cookie)
    		response.addCookie(c1);
    		System.out.println("쿠키 담기 성공");
    	}
    }
    @WebServlet("/GetCookie")
    public class GetCookie extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//1.요청에서 쿠키 얻기
    		Cookie[] cookies = request.getCookies();
    		System.out.println(cookies.length);
    		//2.쿠키 사용하기
    		for (Cookie c : cookies) {
    			String name = c.getName();
    			String value = c.getValue();
    			System.out.println(name+"\t"+value);
    		}
    	} 
    }

     

     

     

    참고

    처음 해보는 Servlet&JSP 웹 프로그래밍 (오정임 지음, 루비페이퍼)

    http://wellnwill.com/tutorial/jee/servlet/servlet-scopes.php

     

     

     

    댓글