Spring

[Spring] MVC 19편 - 웹 페이지 만들기 (1)

dev-nadan 2025. 8. 18. 20:46

이번 편부터는 실제로 상품 관리 웹 애플리케이션을 만들어보면서 스프링 MVC와 타임리프를 활용하는 과정을 다룬다.

앞에서 배운 MVC의 핵심 개념들을 이제는 실무 예제에 적용해보는 단계라고 보면 된다.


1. 프로젝트 생성

먼저 start.spring.io를 이용해 프로젝트를 생성한다.

  • Project: Gradle Project
  • Language: Java
  • Spring Boot: 3.x 
  • Group: hello
  • Artifact: item-service
  • Package name: hello.itemservice
  • Packaging: Jar
  • Java: 17
  • Dependencies: Spring Web, Thymeleaf, Lombok

애플리케이션을 실행하면 http://localhost:8080 에서 Whitelabel Error Page가 보이면 정상 동작이다.


2. Welcome 페이지 추가

resources/static/index.html 파일을 만들어 초기 진입 페이지를 설정한다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li>상품 관리
        <ul>
            <li><a href="/basic/items">상품 관리 - 기본</a></li>
        </ul>
    </li>
</ul>
</body>
</html>

실행 후 http://localhost:8080 접속 시 위 페이지가 뜨면 성공이다.


3. 요구사항 분석

우리가 구현할 서비스는 상품 관리 시스템이다.

 

상품 도메인 모델

  • 상품 ID
  • 상품명
  • 가격
  • 수량

주요 기능

  • 상품 목록 조회
  • 상품 상세 조회
  • 상품 등록
  • 상품 수정

개발 프로세스

  1. 디자이너: 화면 디자인 산출물 제작
  2. 웹 퍼블리셔: HTML, CSS로 정적 페이지 작성
  3. 백엔드 개발자: 비즈니스 로직 구현, 뷰 템플릿 변환 및 화면 흐름 제어
만약 React, Vue 같은 프론트엔드 프레임워크를 사용한다면, 백엔드는 HTML 뷰 대신 HTTP API를 제공하게 된다.

 


4. 상품 도메인 개발

Item 엔티티

@Data
public class Item {
    private Long id;
    private String itemName;
    private Integer price;
    private Integer quantity;

    public Item() {}
    public Item(String itemName, Integer price, Integer quantity) {
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }
}

 

ItemRepository

@Repository
public class ItemRepository {
    private static final Map<Long, Item> store = new HashMap<>();
    private static long sequence = 0L;

    public Item save(Item item) {
        item.setId(++sequence);
        store.put(item.getId(), item);
        return item;
    }

    public Item findById(Long id) {
        return store.get(id);
    }

    public List<Item> findAll() {
        return new ArrayList<>(store.values());
    }

    public void update(Long itemId, Item updateParam) {
        Item findItem = findById(itemId);
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
    }

    public void clearStore() {
        store.clear();
    }
}

5. 상품 저장소 테스트

class ItemRepositoryTest {
    ItemRepository itemRepository = new ItemRepository();

    @AfterEach
    void afterEach() {
        itemRepository.clearStore();
    }

    @Test
    void save() {
        Item item = new Item("itemA", 10000, 10);
        Item savedItem = itemRepository.save(item);
        Item findItem = itemRepository.findById(item.getId());
        assertThat(findItem).isEqualTo(savedItem);
    }
}

6. 회고

이번 단계에서는 웹 애플리케이션의 골격을 만들고, 상품 관리 도메인과 저장소를 구축했다.

여기서 중요한 깨달음은 “스프링 프로젝트를 시작할 때는 항상 도메인 모델을 먼저 설계하고, 이를 기반으로 나머지 기능을 확장한다”는 점이다.

예전에는 프로젝트를 만들 때 화면부터 신경 쓰곤 했는데, 이렇게 도메인을 먼저 설계하고 테스트까지 작성하니 전체 구조가 훨씬 안정적이라는 걸 알게 되었다.

실무에서도 항상 기능 구현보다 도메인과 저장소 설계를 우선으로 해야 한다는 교훈을 얻었다.