๐Ÿ“• Spring Framework/Spring Project

2022.05.22 ใ€ŒShopping Cart API [Ver.2]ใ€

GroovyArea 2022. 5. 22. 10:50
์–ด์ œ๋ถ€ํ„ฐ ์žฅ๋ฐ”๊ตฌ๋‹ˆ API ๊ตฌํ˜„์— ๋Œ€ํ•ด ๊ณ ๋ฏผ์„ ์ •๋ง ๋งŽ์ด ํ–ˆ๋‹ค.
๋‹น์—ฐํžˆ DB๋ฅผ ์ด์šฉํ•˜๋‹ค ์ฟ ํ‚ค๋กœ ๊ตฌํ˜„ํ•ด๋ณด๋ ค๋Š” ์‹œ๋„๊ฐ€ ์ฒ˜์Œ์ด๋ผ ๋” ๊ฐœ๋…์ด ๋‚ฏ์„ค์—ˆ๋‹ค.
์ถ”๊ฐ€ ๋ฐ ์กฐํšŒ๋Š” ๋๋‚ฌ๋Š”๋ฐ, ์˜ค๋Š˜ ์•„์นจ ๋‹ค์‹œ ๋ณด๋‹ˆ ์ถ”๊ฐ€์—์„œ ์ด์ƒํ•œ ๋กœ์ง์ด ์žˆ์—ˆ๊ณ , ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์„œ ์ˆ˜์ •์„ ํ•˜๊ณ  
์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ • ๋ฐ ์‚ญ์ œ API๋ฅผ ์ž‘์„ฑํ•ด๋ณด์•˜๋‹ค. 
API๋ฅผ ์„ค๊ณ„ํ•˜๋ฉด์„œ ๋ฌธ์ œ์ ๋“ค๊ณผ ํ™•์‹คํžˆ ์•Œ๊ฒŒ ๋œ ์ ์„ ์ •๋ฆฌํ•ด๋ณด๊ฒ ๋‹ค~

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ

์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ์กฐํšŒํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ณง ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋“ค์–ด์žˆ๋Š” ์ƒํ’ˆ ๋ชฉ๋ก์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๊ฒ ๋‹ค๋Š” ๊ฒƒ. 

๊ทธ ์ƒํ’ˆ ๋ชฉ๋ก์˜ ๊ฐ์ฒด๋ฅผ ์„ค๊ณ„ํ–ˆ๋‹ค. 

public class CartItemDTO {

    private final Integer productNo;
    private Integer productStock;
    private final String productPrice;

    public CartItemDTO(Integer productNo, Integer productStock, String productPrice) {
        this.productNo = productNo;
        this.productStock = productStock;
        this.productPrice = productPrice;
    }

    public Integer getProductNo() {
        return productNo;
    }

    public Integer getProductStock() {
        return productStock;
    }

    public String getProductPrice() {
        return productPrice;
    }

    public void setProductStock(Integer productStock) {
        this.productStock = productStock;
    }

}

 

=> ์ตœ๋Œ€ํ•œ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

/**
 * ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ ๋ฉ”์„œ๋“œ
 *
 * @param request servlet Request
 * @return Message ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก
 */
@Auth(role = Auth.Role.BASIC_USER)
@GetMapping
public Message getCartList(HttpServletRequest request) throws UnsupportedEncodingException {
    Cookie[] requestCookies = request.getCookies();
    List<CartItemDTO> cartList;
    Cookie responseCookie;

    /* ์ฟ ํ‚ค๊ฐ€ ์กด์žฌํ•  ๋•Œ ์นดํŠธ ์ฟ ํ‚ค ๋ฐ˜ํ™˜ */
    if (requestCookies != null) {
        responseCookie = CookieUtil.getCartCookie(requestCookies);

        /* ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ •๋ณด๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ */
        if (responseCookie != null) {
            String cookieValue = responseCookie.getValue();
            Map<Integer, CartItemDTO> cartDTOMap = JsonUtil.stringToMap(URLDecoder.decode(cookieValue, ENC_TYPE), Integer.class, CartItemDTO.class);

            if (cartDTOMap != null && !cartDTOMap.isEmpty()) {
                cartList = new ArrayList<>(cartDTOMap.values());
                return new Message
                        .Builder(cartList)
                        .httpStatus(HttpStatus.OK)
                        .mediaType(MediaType.APPLICATION_JSON)
                        .build();
            }
        }
    }
    return new Message
            .Builder(CART_EMPTY)
            .httpStatus(HttpStatus.NO_CONTENT)
            .build();
}

๋Œ€๋žต์ ์ธ ํ๋ฆ„

  • ์„œ๋ธ”๋ฆฟ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ฟ ํ‚ค๋ฅผ ๋ฐ›์•„์™€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ฟ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • objectMapper๋กœ json ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด์„ ๋””์ฝ”๋“œ ํ•ด Map ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ List์— ๋‹ด๊ทผ๋‹ค.
  • ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค..

์›๋ž˜ JsonUtil ์ด๋ž€ ํด๋ž˜์Šค๋Š” ์—†๋‹ค. ๋‚ด๊ฐ€ ๋”ฐ๋กœ ๋งŒ๋“  ๊ฒƒ์ธ๋ฐ..

๋”ฐ๋กœ ๋งŒ๋“  utils

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜์ž๋ฉด ์ผ๋ฐ˜ ์œ ํ‹ธ ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šคํ™”์— ๊ตณ์ด Heap ์˜์—ญ์— ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ Bean ๋“ฑ๋ก์„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ๋Œ€์‹  private ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์ž. 

์ถ”๊ฐ€ํ•จ

๋‘ ๋ฒˆ์งธ ๋ฌธ์ œ๋Š” ์ค‘๋ณต๋œ ์ฝ”๋“œ๋‹ค. 

์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด์•ผ ์œ ์ง€๋ณด์ˆ˜์— ํšจ์œจ์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋”ฐ๋กœ Utils๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ–ˆ๋‹ค.

 

public class CookieUtil {

    private static final String COOKIE_KEY = "Chicken";
    private static final String ENC_TYPE = "utf-8";

    /* ์นดํŠธ ์ฟ ํ‚ค ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ */
    public static Cookie getCartCookie(Cookie[] requestCookies) {
        for (Cookie cookie : requestCookies) {
            if (COOKIE_KEY.equals(cookie.getName())) {
                return cookie;
            }
        }
        return null;
    }

    /* ์นดํฌ ์ฟ ํ‚ค ๊ฐ’ ๋””์ฝ”๋”ฉ ํ›„ map ๊ฐ์ฒด ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ */
    public static Map<Integer, CartItemDTO> getCartItemDTOMap (Cookie responseCookie) throws UnsupportedEncodingException {
        String cookieValue = responseCookie.getValue();
        return JsonUtil.stringToMap(URLDecoder.decode(cookieValue, ENC_TYPE), Integer.class, CartItemDTO.class);
    }
}โ€‹

 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ •

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ •์€ ์ถ”๊ฐ€์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ฟ ํ‚ค์— ์žˆ๋Š” ๊ฐ’์„ ๋ฝ‘์•„ ๋””์ฝ”๋“œ ํ›„ Map ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ฐ๊ฐ์˜ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ๋ฐ›์•„์˜จ DTO๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆ˜์ • ํ›„ ๋‹ค์‹œ ์ธ์ฝ”๋”ฉ ํ›„ ์ฟ ํ‚ค์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ํ˜•์‹์ด๋‹ค.

 

/**
 * ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ
 *
 * @param modifyCartDTO ๋ณ€๊ฒฝํ•  ์นดํŠธ ๊ฐ์ฒด
 * @param request       Servlet Request ๊ฐ์ฒด
 * @param response      Servlet Response ๊ฐ์ฒด
 * @return ๋ณ€๊ฒฝ ๋ฉ”์‹œ์ง€
 * @throws UnsupportedEncodingException ์ธ์ฝ”๋”ฉ ๋ฌธ์ œ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ
 * @throws NoCartException              ์ฟ ํ‚ค ์—†์„ ๋•Œ ์˜ˆ์™ธ ๋ฐœ์ƒ
 */
@Auth(role = Auth.Role.BASIC_USER)
@PutMapping
public ResponseEntity<String> modifyCart(@RequestBody(required = true) CartItemDTO modifyCartDTO, HttpServletRequest request,
                                         HttpServletResponse response) throws UnsupportedEncodingException, NoCartException {
    Integer productNo = modifyCartDTO.getProductNo();
    Cookie[] requestCookies = request.getCookies();
    Cookie responseCookie = null;

    /* ์ฟ ํ‚ค๊ฐ€ ์กด์žฌํ•  ๋•Œ ์นดํŠธ ์ฟ ํ‚ค ๋ฐ˜ํ™˜ */
    if (requestCookies != null) {
        responseCookie = CookieUtil.getCartCookie(requestCookies);
    }

    if (responseCookie == null) {
        throw new NoCartException(NULL_MODIFY_COOKIE);
    }

    Map<Integer, CartItemDTO> cartDTOMap = CookieUtil.getCartItemDTOMap(responseCookie);

    /* ๊ธฐ์กด ์ƒํ’ˆ ๊ฐ์ฒด ์‚ญ์ œ */
    cartDTOMap.remove(productNo);

    /* ๋„˜์–ด์˜จ ์ƒํ’ˆ ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ */
    cartDTOMap.put(productNo, modifyCartDTO);

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

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

=> ์ถ”๊ฐ€ ํ•ธ๋“ค๋Ÿฌ์™€ ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค.. ์ €๊ฑธ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฆฌํ• ๊นŒ..

์ฝ”๋“œ ์„ค๊ณ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๋‚˜๋„ ์‹ถ๋‹ค.

 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ๋Š” ๋‹จ์ผ ์ƒํ’ˆ์˜ ์‚ญ์ œ์ด๋ฏ€๋กœ ๋ณ€๊ฒฝ๊ณผ ๊ฑฐ์˜ ๋น„์Šทํ•˜๋‹ค.

 

/**
 * ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ์‚ญ์ œ ๋ฉ”์„œ๋“œ
 *
 * @param deleteCartDTO ์‚ญ์ œํ•  ์นดํŠธ ๊ฐ์ฒด
 * @param request       Servlet Request ๊ฐ์ฒด
 * @param response      Servlet Response ๊ฐ์ฒด
 * @return ์‚ญ์ œ ๋ฉ”์‹œ์ง€
 * @throws UnsupportedEncodingException ์ธ์ฝ”๋”ฉ ๋ฌธ์ œ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ
 * @throws NoCartException              ์ฟ ํ‚ค ์—†์„ ๋•Œ ์˜ˆ์™ธ ๋ฐœ์ƒ
 */
@Auth(role = Auth.Role.BASIC_USER)
@DeleteMapping
public ResponseEntity<String> deleteCart(@RequestBody CartItemDTO deleteCartDTO, HttpServletRequest request,
                                         HttpServletResponse response) throws NoCartException, UnsupportedEncodingException {
    Integer productNo = deleteCartDTO.getProductNo();
    Cookie[] requestCookies = request.getCookies();
    Cookie responseCookie = null;

    if (requestCookies != null) {
        responseCookie = CookieUtil.getCartCookie(requestCookies);
    }

    if (responseCookie == null) {
        throw new NoCartException(NULL_REMOVE_COOKIE);
    }

    Map<Integer, CartItemDTO> cartDTOMap = CookieUtil.getCartItemDTOMap(responseCookie);

    /* ํ•ด๋‹น ์ƒํ’ˆ ๋งต์—์„œ ์‚ญ์ œ */
    cartDTOMap.remove(productNo);

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

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

 

์ค‘๋ณต๋œ ์ฝ”๋“œ์˜ ๋ฆฌํŒฉํ„ฐ๋ง์„ ๊ฑฐ์ณ์•ผ ํ•  ๊ฒƒ ๊ฐ™์€ ๋А๋‚Œ์ด ๋“ ๋‹ค.

 

์ฐธ์กฐ : https://passionha.tistory.com/403?category=457136 

 

AJAX๋ฅผ ํ†ตํ•ด json object ๋ฐฐ์—ด๋ฐ์ดํ„ฐ๋ฅผ controller์˜ List<Map>ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ณด๋‚ด๊ธฐ

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 //JSP ๋‚ด JS๋ถ€๋ถ„ //f_arrAnlys ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด์„œ ๋ฐ์ดํ„ฐ ๋„ฃ์–ด๋‘” ์ „์—ญ๋ฐฐ์—ด function fn_exec(){     var arrPObj =..

passionha.tistory.com

 

๋ฐ˜์‘ํ˜•