1. 들어가며: 모든 것이 연결되다
지난 포스팅까지 백엔드 API와 DB 로직을 모두 완성했습니다. 하지만 API는 호출해 주는 사람이 없으면 무용지물입니다. 이번 포스팅에서는 stock_list.html에 매수/매도 버튼을 달고, 자바스크립트(Fetch API)를 통해 실제로 서버에 주문을 넣는 과정을 담았습니다.
그리고 그 과정에서 마주친 Thymeleaf 버전 호환성 문제와 그 해결책도 공유합니다.
2. UI 구현: 버튼에 생명 불어넣기
기존의 시세표 옆에 '주문' 칸을 만들고, 수량 입력(input)과 매수/매도 버튼(button)을 배치했습니다.
초기 접근 (에러 발생) 처음에는 타임리프 문법을 이용해 단순하게 작성했습니다.
<button th:onclick="|buyStock('${stock.code}')|">매수</button>
하지만 서버를 켜자마자 TemplateProcessingException이 발생했습니다. 로그를 분석해 보니 **"보안상의 이유로 이벤트 핸들러(onclick 등) 내부에 문자열 변수를 직접 넣는 것을 금지한다"**는 내용이었습니다. (XSS 공격 방지)
해결책 (Data 속성 활용) 타임리프가 권장하는 대로, 데이터를 data-* 속성에 따로 담고 자바스크립트에서 꺼내 쓰는 방식으로 변경하여 해결했습니다.
<button class="btn btn-success"
th:data-code="${stock.code}"
onclick="buyStock(this.getAttribute('data-code'))">매수</button>
3. JS 구현: Fetch API로 주문서 발송
백엔드 컨트롤러가 OrderRequestDto (JSON)를 기다리고 있으므로, 자바스크립트에서도 형식을 맞춰서 보내줘야 합니다.
function buyStock(code) {
// 1. 입력된 수량 가져오기
const quantity = document.getElementById('quantity_' + code).value;
// 2. JSON 데이터 포장
const requestData = {
userId: 29, // (테스트용 ID)
code: code,
quantity: Number(quantity)
};
// 3. 서버로 전송 (POST)
fetch('/orders/buy', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
})
.then(response => {
if (response.ok) {
alert("매수 성공!");
window.location.reload(); // 잔액 변화 확인을 위해 새로고침
} else {
alert("실패");
}
});
}

4. 통합 테스트: 떨리는 첫 거래
모든 코드를 적용하고 서버를 재시작했습니다. DB에는 테스트용 유저(ID: 29)에게 가상의 현금 10억 원을 넣어두었습니다.
- 화면: 비트코인 1개 매수 버튼 클릭 -> "매수 성공!" 알림창 등장.
- DB 확인 (Orders): BUY 주문 로그가 정확히 생성됨.
- DB 확인 (StockHolding): 나의 주식 보유 목록에 KRW-BTC 1개가 추가됨.
- DB 확인 (Account): 잔액이 정확히 비트코인 가격만큼 차감됨.
이로써 [클라이언트 -> 컨트롤러 -> 서비스 -> 레포지토리 -> DB]로 이어지는 전체 데이터 파이프라인이 정상 작동함을 검증했습니다.



5. 마치며
드디어 "가상" 주식 거래소가 "실제" 동작하는 서비스가 되었습니다. 하지만 아직 부족한 점이 있습니다. 매수는 성공했지만, "내가 산 주식 목록(내 잔고)"을 볼 수 있는 화면이 없습니다.
다음 포스팅에서는 [마이페이지 / 내 잔고 조회] 기능을 구현하여, 내가 투자한 주식들의 수익률을 한눈에 볼 수 있도록 만들어 보겠습니다.
'개발 공부 > 프로젝트' 카테고리의 다른 글
| [사이드 프로젝트] 가상 주식 거래소 만들기 (12) - 화면 연동과 500 에러의 습격 (JPA 순환 참조) (0) | 2026.01.07 |
|---|---|
| [사이드 프로젝트] 가상 주식 거래소 만들기 (11) - 내 자산 조회 API 설계와 RESTful 리팩토링 (1) | 2026.01.07 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (9) - 주문을 받는 창구, OrderController와 REST API (0) | 2025.12.10 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (8) - 핵심 비즈니스 로직 구현 (매수/매도와 트랜잭션) (0) | 2025.12.09 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (7) - 거래를 위한 도메인 설계와 JPA Entity (0) | 2025.12.09 |