[JSP]세션 사용법(예제포함)

Inung_92·2023년 1월 25일
0

JSP

목록 보기
5/5
post-thumbnail

들어가기에 앞서

아직 세션의 개념이나 기본적인 부분을 알지 못한다면 앞선 게시글에 쿠키와 함께 설명한 적이 있다.
해당 게시글을 보려면 👉🏽여기를 클릭하자.

세션은 서버에 이용자 정보를 저장하는 객체인만큼 로그인 정보를 저장하는 것 외에도 장바구니 기능 등을 구현할 때 사용하기도 한다. 그래서 오늘은 세션의 사용법을 알아보며 간단하게 장바구니 기능을 구현하는 코드도 같이 들여다보자.


세션에 대해서

특징

세션과 쿠키의 가장 큰 차이점은 쿠키는 클라이언트의 위치에, 세션은 서버상에 객체로 존재한다는 것이다. 다음은 세션의 특징을 나열한 것이며, 아래 그림을 보면서 같이 이해해보자.

  • 서버에서 사용자의 정보(상태)를 유지
  • 서버와의 관계를 유지하기 위한 수단
  • 클라이언트의 요청이 발생하면 자동 생성(쿠키와 동일)
  • 클라이언트의 특정 위치에 저장되는 것이 아니라 서버 상에 객체로서 존재
  • 쿠키와 달리 서버에서만 접근이 가능하여 보안유지 가능
  • 웹 브라우저 종료 또는 일정시간동안 요청이 없으면 소멸
  • 대표적으로 로그인 정보 및 사용자 환경설정 등을 유지하며 필요에 따라 장바구니 등이 기능 담당

세션의 메서드

메서드설명
setAttribute(String name, Object value)세션에 Map형태의 데이터 저장
getAttribute(String name)세션에서 key값을 호출하여 value를 얻음
getAttributeNames()세션에 저장된 모든 데이터의 이름을 얻음
getId()자동 생성된 세션의 유니크한 아이디를 얻음(각 브라우저에 해당하는 값)
isNew()세션이 최초 생성된 것인지 이전에 생성된 것인지 구분
setMaxInactiveInterval(int second)세션의 유효시간을 설정(초 단위)
getMaxInactiveInterval()세션의 유효시간을 얻으며, 가장 최근 요청시점을 기준으로 카운트
removeAttribute(String name)세션에서 특정 데이터만 제거
invalidate()세션의 모든 데이터를 삭제
getCreationTime()세션이 생성된 시간을 구함. 기준은 1970-1-1 이후 시간, 단위 1/1000초
getLastAccessedTime()웹 브라우저가 가장 마지막에 세션에 접근한 시간을 구함. 위와 동일

여기서 invalidate()는 세션의 모든 데이터를 삭제하고 바로 세션을 소멸시키는 것을 의미하지는 않는다. 아이디 값을 제외한 나머지 정보를 접근할 수 없게 제거한다는 의미이다. invalidate() 후 세션의 아이디 값을 받아올 수 있는 것으로 보아 현재 페이지에서 세션이 아예 사라진 것은 아니다.

세션의 생성

<%@ page session = "true" %>

세션은 JSP에서 기본적으로 내장객체로서 생성이 되어있다. 또는 아래와 같이 메서드를 통해 반환받을 수 있다.

request.getSession();

현재 요청과 관련된 session 객체를 반환할 것이다. 해당 객체는 HttpSession 인터페이스를 구현한다. 여기서 getSession() 사용 시 session이 이전부터 존재하면 해당 session을 반환하고, 존재하지 않는다면 새롭게 session을 생성해서 반환한다.

세션의 유효시간 설정

⚡️web.xml 설정파일을 통한 방법(단위 - 분)

<session-config>
  <session-timeout>30</session-timeout>
	<!--
		태그 사이 값(현재 30)을 0 또는 음수로 설정할 경우 유효시간 없이 무제한 유지
	-->
</session-config>

⚡️메서드 방식(단위 - 초)

<%
	sesssion.setMaxInactiveInterval(60 * 60);
%>

예제 - 장바구니 상품정보 유지

위 사진과 같이 상품을 장바구니에 담기 위하여 클릭한 경우를 가정하여 예제에 대한 코드를 작성해보자. 장바구니 상품들을 담는 방법에는 쿠키와 DB를 이용하는 방법도 있지만 오늘은 세션을 이용해 보겠다.

⚡️상품 HTML 태그

<div class="product__item__pic set-bg" data-setbg="/data/<%=filename %>">
  <ul class="product__hover">
    <!-- 확대보기 태그 -->
    <li><a href="/data/<%=filename %>" class="image-popup"><span class="arrow_expand"></span></a></li>
    <!-- 좋아요 태그 -->
    <li><a href="#"><span class="icon_heart_alt"></span></a></li>
	<!--
		장바구니 태그에 javascript 액션을 이용하여 메서드 연결
		파라미터 : 현재 상품 id
	-->
    <li><a href="javascript:addCart(<%=product.getProduct_idx()%>)"><span class="icon_bag_alt"></span></a></li>
  </ul>
</div>

위 코드에서 보는 것처럼 a 태그로 아이콘을 구현하고, 해당 아이콘 클릭 시 메서드에 접근하도록 했다.

⚡️addCart() 코드

<script type="text/javascript">
  	//이벤트와 연결된 함수 선언
	function addCart(product_idx){
  		$.ajax({
          type: "GET", //파라미터가 1개이며 간단한 데이터이기에 GET 방식 사용
          url: "/payment/cart.jsp?product_idx=" + product_idx, //파라미터로 전달받은 idx값 전달
          success:function(result, status, xhr){
          	alert(result); //결과 알림
          }
        });
	}
</script>

HTML의 a 태그 클릭 시 해당 product_idx파라미터로 전달받아 ajax의 파라미터로 전달했다. 이제 요청을 보냈으니 뒤(서버)에서 어떤 분주한 일이 일어나는지 가보자.

⚡️Cart.java(Product를 상속받은 장바구니 전용 상품객체)

public class Cart extends Product{
	//부모클래스 보유 멤버변수 : idx, name, brand, price, discount...등
	//상품(Product)가 미보유한 개수 멤버변수를 추가
	private int ea;
	private Member member;
    
    Getter/Setter 생략...
}

상품을 장바구니에 담을때마다 개수를 확인해야하며 어떤 유저가 담은 것인지 구별을 하기 위하여 상품 테이블과 1:1로 대응하는 Product를 상속받아 필요한 부분만 추가한 객체를 이용하였다.

⚡️cart.jsp

//지시부 선언(import 생략...)
<%@ page contentType="text/html;charset=utf-8"%>

//스크립틀릿 영역
<%	
	/*
    세션ID는 로그인 시점에서 생성된 것으로 가정
    이미 세션ID가 이전부터 있었다면 해당 세션ID를 반환하며,
    그렇지 않다면 새로운 ID를 반환
    */
	String sid = session.getId();
	
    //세션으로부터 이전 접속정보를 DTO로 전달
    Member member = session.getAttribute();
    
    //장바구니 객체를 담을 리스트 생성
    List<Cart> cartList = new ArrayList();
    
    //세션 내 장바구니가 하나도 없는 경우에만 리스트 정보 저장
    if(session.getAttribute("cartList") == null){
    	session.setAttribute("cartList", cartList);
    }
    
    //GET 방식으로 전송한 파라미터 및 유저정보를 Empty DTO에 저장
    Cart cart = new Cart(); //empty DTO
    
    String product_idx = request.getParameter("product_idx");
    cart.setProduct_idx(Integer.parseInt(product_idx);
    cart.setMember(member);
    cart.setEa(1); //동일한 상품의 DTO 등록시 증가할 개수
    
    //세션에 저장한 장바구니 리스트를 배열에 대입(위의 cartList가 초기화되는 것을 방지하기 위함)
    List<Cart> sessionCartList = (List)session.getAttribute("cartList");
    sessionCartList.add(cart);
    
    out.print(반환할 결과 실행문 입력....);
%>

위와 같이 코드를 작성하면 세션에 리스트가 저장되어 누적되며, 필요 시 해당 세션의 결과를 json 등으로 반환받아 view를 담당하는 영역에 사용하면 된다. 예제 코드만으로는 어떤 흐름인지 이해하기 쉽지 않으니 그림을 통해 오늘 예제에 대한 흐름을 이해해보자.

예제 개념도

⚡️로그인

로그인을 완료한 유저는 서버에 생성된 세션 객체로부터 세션ID를 저장한 쿠키를 응답 헤더로 전달받았을 것이다. 이후 해당 유저는 쿠키를 들고 사방팔방 돌아다니다가 마음에 드는 상품을 발견하고 해당 상품을 장바구니에 등록할텐데 아래 그림을 보자.

⚡️장바구니 상품 등록

이전 접속정보가 있는 유저의 요청이 들어오면 세션은 세션ID를 비교하여 이전 접속정보를 인지하고, 유저가 보내온 상품의 일부정보를 DTO에 담아 List로 가공된 데이터로서 세션 내에 저장될 것이다. 이렇게 저장된 데이터는 응답 시 클라이언트에게 전송되며 클라이언트는 응답받은 데이터를 가공하여 시각화 할 것이다.


마무리

오늘은 세션에 대한 기본적인 사용과 세션이 보유한 메서드를 이용하여 장바구니 기능을 일부 담당해보는 예제를 알아보았다.

느낀점

  • 세션은 메모리상에서 데이터를 저장하여 처리하기 때문에 DB에서 호출하는 것보다는 성능이 빠름
  • 쿠키에 정보를 저장하는 것보다 서버에 위치한 세션 객체에 저장하는 것이 보안에 있어서 더 안전함
  • 세션의 유지시간을 조절할 수 있어 유연하게 적용가능하지만 유지시간을 명시하지 않을 경우 무제한으로 세션이 유지될 수 있는 부분을 조심해야함
  • 데이터가 제한적이지 않아 다량의 데이터를 보관하는데 유리(쿠키와 비교 시)
  • 대량의 유저가 세션에 대한 정보를 요청 시 서버에 부하가 걸려 일시적 성능 저하가 발생할 수 있음

아직 DB를 이용해 장바구니를 구현해 본 적이 없어서 정확한 차이는 겪어봐야 알겠지만 세션을 사용했을 때 느낀 부분은 위와 같다. 사용할때는 굉장히 간단할 것 같았던 기능들이 구현을 할 때에는 굉장히 머리가 복잡하고 어렵게 느껴진다. 이런 부분들이 익숙해지는 그때까지 더 노력해야겠다.

참고

https://hyejin.tistory.com/230
https://pingfanzhilu.tistory.com/entry/JSP-Session%EC%84%B8%EC%85%98

profile
서핑하는 개발자🏄🏽

0개의 댓글