[Spring] GET요청으로 url 쿼리 파라미터에 포함된 JSON 데이터 사용하기

적용하게 된 이유

장바구니에 있는 상품들 중에 체크박스가 활성화된 상품들만 결제 페이지로 넘기는 작업을 진행하면서
해당 상품들만 어떻게 GET 요청에 담아서 보내야할까? 라는 의문이 들었다.

처음에는 체크박스가 활성화된 상품들을 배열에 담아 해당 배열을 보내주어야 하는데 처음에는 axios를 통해 비동기로 POST 요청으로 해당 상품들의 정보들을 JSON 객체로 넘겨주려했었다.

하지만, 비동기로 요청하게 되면 컨트롤러에서 view를 반환할 때 해당 view에 체크박스가 활성화된 상품들의 데이터를 model에 담아 넘겨줘야하는데

요청에 대한 응답을 성공적으로 넘겨준후에 axios의 then 구문으로 넘어가게되면서 해당 데이터를 넘겨주기 힘들어지는 문제가 발생했다.

(해당 위 방법으로 해결 할수 있을 수도 있다. 하지만 나는 원하는 자료를 찾지못해 아래의 방법으로 해결하였다.)

 

그렇게 고민하던중 url 파라미터체크박스가 활성화된 상품들을 배열에 담아 해당 배열을 JSON.stringify(selectedProducts)로 JSON 문자열로 변환한 후

encodeURIComponent() 함수를 통해 이 JSON 문자열을 URL 형태로 인코딩하여 파라미터에 추가하여 보내는 방법을 사용하였다.

 

만약 이런식으로 GET방식으로 요청을 할 시에, 전달하는 데이터가 아주 많다면 URL의 길이 제한때문에 문제가 발생할 수 있다.

하지만, 장바구니에 있는 상품들이 그렇게 많을 수도 없고 일반적으로 URL의 최대 길이는 2000 ~ 4000자 정도를 안전하게 지원한다고 한다.

그렇기 때문에 문제가 있지 않다고 판단해 나는 이 방법으로 해당 기능을 적용하였다.


적용 방법

내가 적용한 방법은 다음과 같다.
url 파라미터에 아래와 같이 "#goPaymentBtn" (결제하기 버튼)을 클릭하면

체크박스가 활성화된 상품들을 배열에 담아 해당 배열을 JSON.stringify(selectedProducts)로 JSON 문자열로 변환한 후

encodeURIComponent() 함수를 통해 이 JSON 문자열을 URL 형태로 인코딩하여 파라미터에 추가하여 보내었다.

 

아래는 javascript, jquery로 작성한 클라이언트 쪽 코드이다.

cart.js
$(document).on("click", "#goPaymentBtn", () => {
    const soldOutProducts = [];
    const selectedProducts = [];
    $("input[type='checkbox']:checked:not(#cartAllChk)").each((i, checkbox) => {
        const productRow = $(checkbox).closest("tr");
        const productStatus = productRow.find(".price").data("status");

        if (productStatus === "품절") {
            soldOutProducts.push(i);
        } else {
            const productId = $(checkbox).data("product-id");
            selectedProducts.push(productId);
        }
    });

    if (soldOutProducts.length > 0) {
        alert("품절상품은 구매 불가능합니다.");
        return;
    }

    window.location.href = "/user/order?products=" + encodeURIComponent(JSON.stringify(selectedProducts));
});

 

그리고 컨트롤러는 아래와 같이 요청 데이터를 받고, ObjectMapper를 사용해서 요청 URL을 파싱해 원하는 데이터를 뽑아

해당 productId에 해당하는 상품들을 조회하였다.

 

OrderController
@Controller
@RequiredArgsConstructor
public class OrderController {
    private final OrderService orderService;

    @GetMapping("/user/order")
    public String orderProducts(@Login SessionUser sessionUser, Model model, @RequestParam String products) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        List<Long> productIds = objectMapper.readValue(products, new TypeReference<List<Long>>(){});

        List<OrderReqDto> orderReqDtos = productIds.stream()
                .map(id -> orderService.selectOrderInfosByProductId(id))
                .collect(Collectors.toList());
        model.addAttribute("products", orderReqDtos);
        model.addAttribute("totalSize", orderReqDtos.size());
        return "user/payment";
    }
}