본문 바로가기
📕 Spring Framework/Spring Project

2022.05.28 「쿠키 수정」

by GroovyArea 2022. 5. 28.
장바구니 API를 처음 구현해보는 쿠키로 힘들게 짰었다.
오늘 주문 API를 구현하려고 카카오페이 관련 API 탐색 및 구상을 하던 도중 장바구니 데이터를 가지고 결제하는 경우를 떠올렸다. 다시 한번 장바구니 API 동작이 잘 되는지 포스트맨으로 확인을 하던 도중 이상한 쿠키 에러가 발생하는 것을 발견할 수 있었다..
다시 한번 점검을 통해 코드 수정을 하며 단번에 완벽한 코드를 작성한다는 자만심 느꼈던 자신에 반성을 하게 되었다..ㅎㅎ

문제점

  1. 장바구니 상품 추가가 되질 않는다
  2. 쿠키가 다중으로 생성된다

=> 이 두 가지 문제가 제일 컸다

 

기존 코드 

장바구니 쿠키를 수정하여 response 객체에 삽입한다.

빨간색을 보면 쿠키 값 변경 후 response 객체에 다시 저장한다. 이러면 새로운 쿠키 객체가 저장되는 것이다.

문제

새로운 쿠키가 같은 Key를 가진 객체가 생성되어 저장된다. 

=> 내가 원한 건 기존 쿠키를 덮어 씌우는 거였는데

 

해결

기존 쿠키의 값을 얻어와 수정하고, 삭제한다

그 후 새로운 쿠키를 생성 후 업데이트 값을 저장한다.

 

/**
 * 장바구니의 정보를 담은 map 객체를 값으로 장바구니 쿠키를 생성
 *
 * @throws UnsupportedEncodingException 인코딩 문제 시 예외 발생
 */
private void createCartCookie() throws UnsupportedEncodingException {
    responseCartCookie = new Cookie(COOKIE_KEY, URLEncoder.encode(JsonUtil.objectToString(cartDTOMap), ENC_TYPE));
    responseCartCookie.setPath("/api/carts");
}

=> 먼저 새롭게 만들어질 쿠키를 생성 후

 

/**
 * 기존 장바구니 쿠키를 삭제하고 새롭게 만들어진 쿠키를 응답
 *
 * @param response servlet response 객체
 * @throws UnsupportedEncodingException 인코딩 문제 시 예외 발생
 */
private void resetCartCookie(HttpServletResponse response) throws UnsupportedEncodingException {
    responseCartCookie.setMaxAge(KILL_COOKIE);
    createCartCookie();
    response.addCookie(responseCartCookie);
}

=> 기존 쿠키를 삭제하고 만들어진 쿠키를 다시 response에 담는다.

 

/**
 * 단일 상품 장바구니 추가 메서드
 *
 * @param addCartDTO 추가할 장바구니 상품 데이터
 * @param response   servlet Response
 * @return 상태코드 & 메시지
 * @throws UnsupportedEncodingException url 인코드, 디코드 예외
 */
@Auth(role = Auth.Role.BASIC_USER)
@PostMapping
public ResponseEntity<String> addCart(@RequestBody(required = true) CartItemDTO addCartDTO, HttpServletRequest request,
                                      HttpServletResponse response) throws UnsupportedEncodingException {
    productNo = addCartDTO.getProductNo();

    getCartCookie(request);

    /* 응답 장바구니 쿠키가 없을 경우 쿠키 생성 */
    if (responseCartCookie == null) {
        cartDTOMap = new HashMap<>();

        createCartCookie();

        cartDTOMap.put(productNo, addCartDTO);

        responseCartCookie.setValue(URLEncoder.encode(JsonUtil.objectToString(cartDTOMap), ENC_TYPE));
        response.addCookie(responseCartCookie);

        return ResponseEntity.ok().body(ResponseMessage.ADD_MESSAGE.getValue());
    }

    cartDTOMap = getCartItemDTOMap(responseCartCookie);

    CartItemDTO cartItem = cartDTOMap.get(productNo);
    /* 기존 상품이 있을 경우 바꿔치기 해야됨 바뀔 데이터는 수량뿐이다.
    상품 번호 = key, 상품 객체 = value */
    if (cartItem != null) {
        cartItem.setProductStock(addCartDTO.getProductStock() + cartItem.getProductStock());
        cartDTOMap.put(productNo, cartItem);
    }

    cartDTOMap.put(productNo, addCartDTO);

    resetCartCookie(response);

    return ResponseEntity.ok().body(ResponseMessage.ADD_MESSAGE.getValue());
}

중복 코드도 메서드로 분리해 최대한 제거하는 방향으로 갔다

 

결론

얼떨결에 기존 코드를 수정하게 되었다. 처음 써보는 쿠키를 구현한 만큼 잔 실수가 많았던 것 같다. 

이러면서 성장하는 것 아니겠어?

그래도 항상 실행을 해보며 올바른 프로그래밍을 하는 습관을 들여야겠다고 생각했다.

내일은 밤을 새워서라도 주문 API를 완성해야겠다.

반응형