5 분 소요

인프런 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술편을 학습하고 정리한 내용 입니다.

상품 도메인 개발

Item - 상품 객체

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package hello.itemservice.domain.item;  
  
import lombok.Data;  
  
@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 - 상품 저장소

hello.itemservice.domain.item.ItemRepository

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
31
@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();  
    }  
}

참고로 DB는 안쓰고 메모리에서만 동작하도록 하는데

1
2
private static final Map<Long, Item> store = new HashMap<>();  
private static long sequence = 0L;

다음과 같이 전역변수로 HashMap, long 등을 사용할 때는 멀티쓰레드 동시성 문제를 생각하면서 사용하자. (ConcurrentHashMap, AtomicLong)

간단하게 저장, 단일 찾기, 전체 조회, 업데이트, 그리고 맵을 초기화 할 메서드 하나만 만들었다.

이제 테스트 코드를 작성해 보자.

ItemRepositoryTest - 상품 저장소 테스트

hello.itemservice.domain.item.ItemRepositoryTest

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class ItemRepositoryTest {  
  
    ItemRepository itemRepository = new ItemRepository();  
  
    @AfterEach  
    void afterEach() {  
        itemRepository.clearStore();  
    }  
  
    @Test  
    void save() throws Exception {  
        //given  
        Item item = new Item("itemA", 10000, 10);  
        //when  
        Item savedItem = itemRepository.save(item);  
        //then  
        Item findItem = itemRepository.findById(item.getId());  
  
        assertThat(findItem).isEqualTo(savedItem);  
    }  
  
    @Test  
    void findAll() throws Exception {  
        //given  
        Item item1 = new Item("item1", 10000, 10);  
        Item item2 = new Item("item2", 20000, 20);  
        itemRepository.save(item1);  
        itemRepository.save(item2);  
  
        //when  
        List<Item> result = itemRepository.findAll();  
  
        //then  
        assertThat(result.size()).isEqualTo(2);  
        assertThat(result).contains(item1, item2);  
    }  
  
    @Test  
    void updateItem() throws Exception {  
        //given  
        Item item = new Item("item1", 10000, 10);  
        Item savedItem = itemRepository.save(item);  
        Long itemId = savedItem.getId();  
  
        //when  
        Item updateItem = new Item("item2", 20000, 30);  
        itemRepository.update(itemId, updateItem);  
        //then  
        Item findItem = itemRepository.findById(itemId);  
        assertThat(findItem.getItemName()).isEqualTo(updateItem.getItemName());  
        assertThat(findItem.getPrice()).isEqualTo(updateItem.getPrice());  
        assertThat(findItem.getQuantity()).isEqualTo(updateItem.getQuantity());  
    }  
}

이렇게 간단하게 저장 및 단일 조회, 전체 조회, 업데이트를 테스트 해봤다.

결과도 잘 나온다.

그런데 진짜 요즘엔 인텔리제이가 너무 좋아졌다..

이게 말이되나…? ㅋㅋ

상품 서비스 HTML

핵심 비즈니스 로직을 개발하는 동안, 웹 퍼블리셔는 HTML 마크업을 완료했다. 다음 파일들을 경로에 넣고 잘 동작하는지 확인해보자.

부트스트랩 참고로 HTML을 편리하게 개발하기 위해 부트스트랩을 사용했다. 먼저 필요한 부트스트랩 파일을 설치하자.

참고
부트스트랩(Bootstrap)은 웹 사이트를 쉽게 만들 수 있게 도와주는 HTML, CSS, JS 프레임워크이다.
하나의 CSS로 휴대폰, 태블릿, 데스크탑까지 다양한 기기에서 작동한다.
다양한 기능을 제공하여 사용자가 쉽게 웹사이트를 제작, 유지, 보수할 수 있도록 도와준다
- 출처 : 위키백과

HTML, CSS 파일

  • /resources/static/css/bootstrap.min.css부트스트랩 다운로드
  • /resources/static/html/items.html아래 참조
  • /resources/static/html/item.html
  • /resources/static/html/addForm.html
  • /resources/static/html/editForm.html

/resources/static/html/items.html

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE HTML>  
<html>  
<head>  
    <meta charset="utf-8">  
    <link href="../css/bootstrap.min.css" rel="stylesheet">  
</head>  
<body>  
<div class="container" style="max-width: 600px">  
    <div class="py-5 text-center">  
        <h2>상품 목록</h2>  
    </div>  
    <div class="row">  
        <div class="col">  
            <button class="btn btn-primary float-end"  
                    onclick="location.href='addForm.html'" type="button">상품 등록  
            </button>  
        </div>  
    </div>  
    <hr class="my-4">  
    <div>  
        <table class="table">  
            <thead>  
            <tr>  
                <th>ID</th>  
                <th>상품명</th>  
                <th>가격</th>  
                <th>수량</th>  
            </tr>  
            </thead>  
            <tbody>  
            <tr>  
                <td><a href="item.html">1</a></td>  
                <td><a href="item.html">테스트 상품1</a></td>  
                <td>10000</td>  
                <td>10</td>  
            </tr>  
            <tr>  
                <td><a href="item.html">2</a></td>  
                <td><a href="item.html">테스트 상품2</a></td>  
                <td>20000</td>  
                <td>20</td>  
            </tr>  
            </tbody>  
        </table>  
    </div>  
</div> <!-- /container -->  
</body>  
</html>

/resources/static/html/item.html

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE HTML>  
<html>  
<head>  
    <meta charset="utf-8">  
    <link href="../css/bootstrap.min.css" rel="stylesheet">  
    <style>  
        .container {  
            max-width: 560px;  
        }  
    </style>  
</head>  
<body>  
<div class="container">  
    <div class="py-5 text-center">  
        <h2>상품 상세</h2>  
    </div>  
    <div>  
        <label for="itemId">상품 ID</label>  
        <input type="text" id="itemId" name="itemId" class="form-control"  
               value="1" readonly>  
    </div>  
    <div>  
        <label for="itemName">상품명</label>  
        <input type="text" id="itemName" name="itemName" class="form-control"  
               value="상품A" readonly>  
    </div>  
    <div>  
        <label for="price">가격</label>  
        <input type="text" id="price" name="price" class="form-control"  
               value="10000" readonly>  
    </div>  
    <div>  
        <label for="quantity">수량</label>  
        <input type="text" id="quantity" name="quantity" class="form-control"  
               value="10" readonly>  
    </div>  
    <hr class="my-4">  
    <div class="row">  
        <div class="col">  
            <button class="w-100 btn btn-primary btn-lg"  
                    onclick="location.href='editForm.html'" type="button">상품 수정</button>  
        </div>  
        <div class="col">  
            <button class="w-100 btn btn-secondary btn-lg"  
                    onclick="location.href='items.html'" type="button">목록으로</button>  
        </div>  
    </div>  
</div> <!-- /container -->  
</body>  
</html>

/resources/static/html/addForm.html

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE HTML>  
<html>  
<head>  
    <meta charset="utf-8">  
    <link href="../css/bootstrap.min.css" rel="stylesheet">  
    <style>  
        .container {  
            max-width: 560px;  
        }  
    </style>  
</head>  
<body>  
<div class="container">  
    <div class="py-5 text-center">  
        <h2>상품 등록 폼</h2>  
    </div>  
    <h4 class="mb-3">상품 입력</h4>  
    <form action="item.html" method="post">  
        <div>  
            <label for="itemName">상품명</label>  
            <input type="text" id="itemName" name="itemName" class="formcontrol" placeholder="이름을 입력하세요">  
        </div>  
        <div>  
            <label for="price">가격</label>  
            <input type="text" id="price" name="price" class="form-control"  
                   placeholder="가격을 입력하세요">  
        </div>  
        <div>  
            <label for="quantity">수량</label>  
            <input type="text" id="quantity" name="quantity" class="formcontrol" placeholder="수량을 입력하세요">  
        </div>  
        <hr class="my-4">  
        <div class="row">  
            <div class="col">  
                <button class="w-100 btn btn-primary btn-lg" type="submit">상품 등  
                    록</button>  
            </div>  
            <div class="col">  
                <button class="w-100 btn btn-secondary btn-lg"  
                        onclick="location.href='items.html'" type="button">취소</button>  
            </div>  
        </div>  
    </form>  
</div> <!-- /container -->  
</body>  
</html>

/resources/static/html/editForm.html

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE HTML>  
<html>  
<head>  
    <meta charset="utf-8">  
    <link href="../css/bootstrap.min.css" rel="stylesheet">  
    <style>  
        .container {  
            max-width: 560px;  
        }  
    </style>  
</head>  
<body>  
<div class="container">  
    <div class="py-5 text-center">  
        <h2>상품 수정 폼</h2>  
    </div>  
    <form action="item.html" method="post">  
        <div>  
            <label for="id">상품 ID</label>  
            <input type="text" id="id" name="id" class="form-control" value="1"  
                   readonly>  
        </div>  
        <div>  
            <label for="itemName">상품명</label>  
            <input type="text" id="itemName" name="itemName" class="formcontrol" value="상품A">  
        </div>  
        <div>  
            <label for="price">가격</label>  
            <input type="text" id="price" name="price" class="form-control"  
                   value="10000">  
        </div>  
        <div>  
            <label for="quantity">수량</label>  
            <input type="text" id="quantity" name="quantity" class="formcontrol" value="10">  
        </div>  
        <hr class="my-4">  
        <div class="row">  
            <div class="col">  
                <button class="w-100 btn btn-primary btn-lg" type="submit">저장</  
                button>  
            </div>  
            <div class="col">  
                <button class="w-100 btn btn-secondary btn-lg"  
                        onclick="location.href='item.html'" type="button">취소</button>  
            </div>  
        </div>  
    </form>  
</div> <!-- /container -->  
</body>  
</html>

참고로 /resources/static 에 넣어두었기 때문에 스프링 부트가 정적 리소스를 제공한다.

그런데 정적 리소스여서 해당 파일을 탐색기를 통해 직접 열어도 동작하는 것을 확인할 수 있다.

참고
이렇게 정적 리소스가 공개되는 /resources/static폴더에 HTML을 넣어두면, 실제 서비스에서도 공개된다.
서비스를 운영한다면 지금처럼 공개할 필요 없는 HTML을 두는 것은 주의하자.

잘 나온다. (정적 리소스)

태그:

카테고리:

업데이트:

댓글남기기