springboot_message : message
This commit is contained in:
@@ -2,6 +2,9 @@ package hello.itemservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ItemServiceApplication {
|
||||
@@ -10,4 +13,15 @@ public class ItemServiceApplication {
|
||||
SpringApplication.run(ItemServiceApplication.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 직접 등록
|
||||
*/
|
||||
// @Bean
|
||||
// public MessageSource messageSource() {
|
||||
// ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||
// messageSource.setBasenames("messages", "errors"); // messages.properties, errors.properties
|
||||
// messageSource.setDefaultEncoding("utf-8");
|
||||
// return messageSource;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
|
||||
# message 설정
|
||||
spring.messages.basename=messages,config.i18n.messages
|
||||
16
springboot_message/src/main/resources/messages.properties
Normal file
16
springboot_message/src/main/resources/messages.properties
Normal file
@@ -0,0 +1,16 @@
|
||||
hello=안녕
|
||||
hello.name=안녕 {0}
|
||||
|
||||
label.item=상품
|
||||
label.item.id=상품 ID
|
||||
label.item.itemName=상품명
|
||||
label.item.price=가격
|
||||
label.item.quantity=수량
|
||||
|
||||
page.items=상품 목록
|
||||
page.item=상품 상세
|
||||
page.addItem=상품 등록
|
||||
page.updateItem=상품 수정
|
||||
|
||||
button.save=저장
|
||||
button.cancel=취소
|
||||
@@ -0,0 +1,2 @@
|
||||
hello=hello
|
||||
hello.name=hello {0}
|
||||
@@ -15,20 +15,20 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="py-5 text-center">
|
||||
<h2>상품 등록 폼</h2>
|
||||
<h2 th:text="#{page.addItem}">상품 등록 폼</h2>
|
||||
</div>
|
||||
|
||||
<form action="item.html" th:action th:object="${item}" method="post">
|
||||
<div>
|
||||
<label for="itemName">상품명</label>
|
||||
<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
|
||||
<input type="text" id="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요">
|
||||
</div>
|
||||
<div>
|
||||
<label for="price">가격</label>
|
||||
<label for="price" th:text="#{label.item.price}">가격</label>
|
||||
<input type="text" id="price" th:field="*{price}" class="form-control" placeholder="가격을 입력하세요">
|
||||
</div>
|
||||
<div>
|
||||
<label for="quantity">수량</label>
|
||||
<label for="quantity" th:text="#{label.item.quantity}">수량</label>
|
||||
<input type="text" id="quantity" th:field="*{quantity}" class="form-control" placeholder="수량을 입력하세요">
|
||||
</div>
|
||||
|
||||
@@ -36,13 +36,13 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="w-100 btn btn-primary btn-lg" type="submit">상품 등록</button>
|
||||
<button class="w-100 btn btn-primary btn-lg" type="submit" th:text="#{button.save}">상품 등록</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="w-100 btn btn-secondary btn-lg"
|
||||
onclick="location.href='items.html'"
|
||||
th:onclick="|location.href='@{/message/items}'|"
|
||||
type="button">취소</button>
|
||||
type="button" th:text="#{button.cancel}">취소</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="py-5 text-center">
|
||||
<h2>상품 수정 폼</h2>
|
||||
<h2 th:text="#{page.updateItem}">상품 수정 폼</h2>
|
||||
</div>
|
||||
|
||||
<form action="item.html" th:action th:object="${item}" method="post">
|
||||
<div>
|
||||
<label for="id">상품 ID</label>
|
||||
<label for="id" th:text="#{label.item.id}">상품 ID</label>
|
||||
<input type="text" id="id" th:field="*{id}" class="form-control" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label for="itemName">상품명</label>
|
||||
<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
|
||||
<input type="text" id="itemName" th:field="*{itemName}" class="form-control">
|
||||
</div>
|
||||
<div>
|
||||
<label for="price">가격</label>
|
||||
<label for="price" th:text="#{label.item.price}">가격</label>
|
||||
<input type="text" id="price" th:field="*{price}" class="form-control">
|
||||
</div>
|
||||
<div>
|
||||
<label for="quantity">수량</label>
|
||||
<label for="quantity" th:text="#{label.item.quantity}">수량</label>
|
||||
<input type="text" id="quantity" th:field="*{quantity}" class="form-control">
|
||||
</div>
|
||||
|
||||
@@ -40,13 +40,13 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="w-100 btn btn-primary btn-lg" type="submit">저장</button>
|
||||
<button class="w-100 btn btn-primary btn-lg" type="submit" th:text="#{button.save}">저장</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="w-100 btn btn-secondary btn-lg"
|
||||
onclick="location.href='item.html'"
|
||||
th:onclick="|location.href='@{/message/items/{itemId}(itemId=${item.id})}'|"
|
||||
type="button">취소</button>
|
||||
type="button" th:text="#{button.cancel}">취소</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -15,26 +15,26 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="py-5 text-center">
|
||||
<h2>상품 상세</h2>
|
||||
<h2 th:text="#{page.item}">상품 상세</h2>
|
||||
</div>
|
||||
|
||||
<!-- 추가 -->
|
||||
<h2 th:if="${param.status}" th:text="'저장 완료'"></h2>
|
||||
|
||||
<div>
|
||||
<label for="itemId">상품 ID</label>
|
||||
<label for="itemId" th:text="#{label.item.id}">상품 ID</label>
|
||||
<input type="text" id="itemId" name="itemId" class="form-control" value="1" th:value="${item.id}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label for="itemName">상품명</label>
|
||||
<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
|
||||
<input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label for="price">가격</label>
|
||||
<label for="price" th:text="#{label.item.price}">가격</label>
|
||||
<input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label for="quantity">수량</label>
|
||||
<label for="quantity" th:text="#{label.item.quantity}">수량</label>
|
||||
<input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}" readonly>
|
||||
</div>
|
||||
|
||||
@@ -45,13 +45,13 @@
|
||||
<button class="w-100 btn btn-primary btn-lg"
|
||||
onclick="location.href='editForm.html'"
|
||||
th:onclick="|location.href='@{/message/items/{itemId}/edit(itemId=${item.id})}'|"
|
||||
type="button">상품 수정</button>
|
||||
type="button" th:text="#{page.updateItem}">상품 수정</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="w-100 btn btn-secondary btn-lg"
|
||||
onclick="location.href='items.html'"
|
||||
th:onclick="|location.href='@{/message/items}'|"
|
||||
type="button">목록으로</button>
|
||||
type="button" th:text="#{page.items}">목록으로</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<div class="container" style="max-width: 600px">
|
||||
<div class="py-5 text-center">
|
||||
<h2>상품 목록</h2>
|
||||
<h2 th:text="#{page.items}">상품 목록</h2>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -17,7 +17,7 @@
|
||||
<button class="btn btn-primary float-end"
|
||||
onclick="location.href='addForm.html'"
|
||||
th:onclick="|location.href='@{/message/items/add}'|"
|
||||
type="button">상품 등록</button>
|
||||
type="button" th:text="#{page.addItem}">상품 등록</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>상품명</th>
|
||||
<th>가격</th>
|
||||
<th>수량</th>
|
||||
<th th:text="#{label.item.id}">ID</th>
|
||||
<th th:text="#{label.item.itemName}">상품명</th>
|
||||
<th th:text="#{label.item.price}">가격</th>
|
||||
<th th:text="#{label.item.quantity}">수량</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package hello.itemservice.message;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
public class MessageSourceTest {
|
||||
|
||||
@Autowired
|
||||
MessageSource messageSource;
|
||||
|
||||
@Test
|
||||
void helloMessage() {
|
||||
String result = messageSource.getMessage("hello", null, null);
|
||||
assertThat(result).isEqualTo("안녕");
|
||||
}
|
||||
|
||||
@Test
|
||||
void notFoundMessageCode() {
|
||||
assertThatThrownBy(() -> messageSource.getMessage("no_code", null, null))
|
||||
.isInstanceOf(NoSuchMessageException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notFoundMessageCodeDefaultMessage() {
|
||||
String result = messageSource.getMessage("no_code", null, "기본 메시지", null);
|
||||
assertThat(result).isEqualTo("기본 메시지");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argumentMessage() {
|
||||
String message = messageSource.getMessage("hello.name", new Object[]{"Spring"}, null);
|
||||
assertThat(message).isEqualTo("안녕 Spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultLang() {
|
||||
assertThat(messageSource.getMessage("hello", null, null)).isEqualTo("안녕");
|
||||
assertThat(messageSource.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
|
||||
}
|
||||
|
||||
@Test
|
||||
void enLang() {
|
||||
assertThat(messageSource.getMessage("hello", null, Locale.ENGLISH)).isEqualTo("hello");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user