Tiny Bunny
본문 바로가기
💻/Javascript

[JS] 자바스크립트 배열 Json타입 변환, ajax를 통해 controller에 넘기기

by soonybutter 2025. 1. 5.
728x90

 

 

쇼핑몰 장바구니 기능을 구현하며,

각각 카테고리 별 제품을 화면에 띄워주며 자바스크립트를 이용해 배열에 담았다.

 

이 배열을 Json타입으로 바꿔서 ajax를 이용해 보내는 방법을 정리해보려 한다. ☺️

 

 

1. 자바스크립트 배열에 담기

 

먼저 상품명, 수량, 가격 / 조립여부, 조립가격, 수량/ 견적 이름자바스크립트 배열에 담아야했다.

담기버튼을 클릭하면 addToCart()를 통해 productName과 productPrice를 가져오도록 한다.

 

그리고 active된 component의 이름을 배열 Name으로 지정한 후, 

 

currentCart[componentName] = {
            name: productName,
            price: parseInt(productPrice),
            quantity: 1, // 기본 수량 :1
        };

형식으로 배열에 담아지도록 코드를 짰다.

//견적 담을 장바구니 배열
let currentCart = {};

//조립 신청 서비스 신청 여부
radioButtons.forEach(radio => {
        radio.addEventListener('change', () => {
            if (radio.value === 'requested' && radio.checked) {
                // 조립 신청이 선택되었을 때
                if (!isAssemblyRequested) {
                    isAssemblyRequested = true;
                    currentCart['assembly'] = { name: '조립 서비스', price: assemblyPrice, quantity: 1 };
                }
            } else if (radio.value === 'not_requested' && radio.checked) {
                // 조립 미신청이 선택되었을 때
                if (isAssemblyRequested) {
                    isAssemblyRequested = false;
                    delete currentCart['assembly'];
                }
            }
            updateTotalPrice(); // 총 가격 즉시 업데이트
        });
    });
    
    
// 담기 버튼 클릭 시 장바구니에 상품 이름 및 수량 담는 함수
function addToCart(productName, productPrice) {
    const activeComponent = document.querySelector('.component.active');

    if (activeComponent) {
        const productDetail = activeComponent.querySelector('#product-detail');
        const productPriceDiv = activeComponent.querySelector('#product-price');
        const quantityControls = createQuantityControls(productPrice);

        if (productDetail) {
            productDetail.innerHTML = `<p>${productName}</p>`; // 제품 이름 출력
        }
        if (productPriceDiv) {
            productPriceDiv.innerHTML = ''; // 기존 가격 제거
            productPriceDiv.appendChild(quantityControls); // 수량 조절 추가
        }

        // 장바구니에 추가
        const componentName = activeComponent.dataset.component;
        currentCart[componentName] = {
            name: productName,
            price: parseInt(productPrice),
            quantity: 1, // 기본 수량 :1
        };

        updateTotalPrice(); // 총합 업데이트
    }
}

 

견적 이름과 조립신청여부는 이렇게 배열에 저장했다.

// 견적 이름 및 조립 신청 여부를 currentCart에 추가
currentCart['quoteName'] = quoteName;
currentCart['assemblyStatus'] = isAssemblyRequested ? '조립 신청' : '조립 미신청';

 

여기까지 실행하면, 화면 상에선 이렇게 카트에 담긴 모습이 된다.

콘솔 창에 찍어보면 배열 형태로 각 component마다 name과 price, quantity가 잘 담아진 것을 확인할 수 있다.

담기 기능
배열 형식으로 담긴 상태

 

 

 

 

2. 자바스크립트 배열 ➡️ JSON타입 변환하기

 

ajax를 사용해 컨트롤러에 보내주어야 하기때문에,

배열을 JSON 타입으로 변환해줬다.

 

* JS배열을 JSON 으로 변환

 

key, value 및 기본 형태의 배열을 JSON 형태로 변환할 수 있다.

 

1. JSON.stringify()

: JSON으로 넘어온 데이터를 string형태로 변환한다.

: JSON -> string

 

2.JSON.parse()

: string 형태 및 각종 형태를 JSON으로 변환한다.

 

 

// JSON으로 변환
const jsonCart = JSON.stringify(currentCart);

 

나는 JSON.stringify()를 통해 currentCart 배열을 JSON형태로 변환해줬다.

 

확인 차 콘솔창에 찍어보면, JSON형식으로 잘 바뀌어 진 것을 확인할 수 있다.

 

 

 

3. ajax 통해 서버로 전송하기

 

- URL에 controller에서 mapping해줄 URL를 적어준다.

일단 임시로 mapping URL을 이렇게 설정했다.

'http://localhost:8080/api/items'

 

'POST방식으로 body에 jsonCart를 담아 보낸다.'

 

//서버로 전송
fetch('http://localhost:8080/api/items', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: jsonCart,
})
    .then((response) => {
        if (!response.ok) {
            throw new Error('견적 저장 실패');
        }
        return response.json();
    })
    .then((data) => {
        alert('견적이 저장되었습니다.');
        console.log('서버 응답:', data);
    })
    .catch((error) => {
        console.error('저장 오류:', error);
        alert('견적 저장 중 오류가 발생했습니다.');
    });

 

 

 

 

 

4. controller에서 Map형태로 변환하여 받기

 

 

controller를 만들어준 뒤, 

@RestController (REST방식으로 사용하겠다.) 어노테이션을 적어준 후, URL도 매핑해준다.

 

@PostMapping("/items")

HTTP POST방식으로 요청이 들어올 것이고, 이 경우에 ("/items")라는 특정 URL로 매핑되도록 설정해준다.

즉, 클라이언트가 Post 매서드로 /items 라는 URL에 데이터를 보낼 경우, 이 메서드가 실행된다.

 

public Map<String,Object> receiveItems

: 반환 타입이 Map<String, Object> 이므로, JSON 형태의 데이터를 반환할 수 있게 Map 형태로 반환된다.

따라서 클라이언트가 데이터를 JSON 형식으로 전송하면 이 메서드도 JSON형식으로 응답하게 된다.

 

@RequestBody Map<String, Object> items

: @RequestBody는 HTTP 요청의 body에 포함된 데이터(이 경우 JSON 형식!)를 Java객체로 변환해주는 어노테이션이다.

: 여기에서 요청 본문을 Map<String, Object> 형태로 변환시킨다.

결과적으로 클라이언트가 보낸 JSON 데이터가 Map 형식으로 매핑되는 것이다! 

 

package com.boot.selftop_web.quote.controller;

import java.util.Map;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class CartController {
	
	
	@PostMapping("/items")
	public Map<String, Object> receiveItems(@RequestBody Map<String, Object> items) {
        
        return items;
    }

}

 

 

 

콘솔창을 통해 JSON타입의 견적이 성공적으로 서버로 넘겨져 Map 형식으로 매핑되어 넘겨진 것을 확인할 수 있다.

2025-01-05T00:33:36.182+09:00 DEBUG 12516 --- [SelfTop_web] [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet        : POST "/api/items", parameters={}
2025-01-05T00:33:36.182+09:00 DEBUG 12516 --- [SelfTop_web] [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.boot.selftop_web.quote.controller.CartController#receiveItems(Map)
2025-01-05T00:33:36.222+09:00 DEBUG 12516 --- [SelfTop_web] [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [{CPU={name=AMD 라이젠5-5세대 7500F (라파엘) (멀티팩(정품)), price=1226, quantity=1}, RAM={name=ESSENCORE KLEVV DD (truncated)...]
2025-01-05T00:33:36.224+09:00 DEBUG 12516 --- [SelfTop_web] [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2025-01-05T00:33:36.224+09:00 DEBUG 12516 --- [SelfTop_web] [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [{CPU={name=AMD 라이젠5-5세대 7500F (라파엘) (멀티팩(정품)), price=1226, quantity=1}, RAM={name=ESSENCORE KLEVV DD (truncated)...]

 

 

 

 

 

 

728x90

TOP

Designed by 티스토리