이 글은 Velog에서 이전한 글입니다. Velog 원문 보기
✏️ 메시지, 국제화 글을 작성했다.
이번에는 내가 만들던 게시판에 메시지, 국제화를 적용하려 한다.
사실 나의 게시판은 해외 사람이 사용할 일이 없기 때문에 국제화를 할 필요가 없다. 그러나 공부 차원에서 적용하려고 한다.
⭐️ 메시지
먼 메시지를 추가 등록하자.
board.main=게시판 메인 페이지
label.title=제목
label.author=작성자
label.content=내용
label.imageFile=이미지 파일
label.createdDate=작성 시간
label.modifiedDate=수정 시간
label.search=검색어:
page.write=게시글 작성
page.list=게시글 목록
page.modified=게시글 수정
button.write=게시글 작성
button.delete=게시글 삭제
button.modified=게시글 수정
button.list=게시글 목록
button.search=검색
타임리프 메시지 적용
타임리프의 메시지 표현식 #{...}를 사용하면 스프링의 메시지를 편리하게 조회할 수 있다.
예를 들어서 방금 등록한 '제목'이라는 이름을 조회하려면 #{label.title}이라고 하면 된다.
렌더링 전
<div th:text="#{label.title}"></div>
렌더링 후
<div>제목</div>
타임리프 템플릿 파일에 메시지를 적용해보자.
아래는 boardWrite.html에 적용한 것이다. 코드 중 메시지 표현식이 적용된 body 부분만 첨부했다.
boardWrite.html
<body>
<div class="container">
<h1 th:text="#{page.write}">게시글 작성</h1>
<form th:action="@{/board/write}" th:object="${post}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="title" th:text="#{label.title}">제목</label>
<input type="text" id="title" th:field="*{title}" required onkeyup="checkInputLength()">
<span id="titleLengthMessage"></span>
</div>
<div class="form-group">
<label for="author" th:text="#{label.author}">작성자</label>
<input type="text" id="author" th:field="*{author}" required onkeyup="checkInputLength()">
<span id="authorLengthMessage"></span>
</div>
<div class="form-group">
<label for="content" th:text="#{label.content}">내용</label>
<textarea id="content" th:field="*{content}" rows="8" required></textarea>
<strong>이미지 파일<input type="file" name="file"></strong>
<li>첨부파일 기능 구현 중..<input type="file" name="attachFile"></li>
</div>
<button type="submit" class="btn" id="submitButton" th:text="#{button.write}">작성하기</button>
</form>
</div>
</body>
- 페이지 이름에 적용
<h1 th:text="#{page.write}">게시글 작성</h1>
- label에 적용
<label for="title" th:text="#{label.title}">제목</label> <label for="title" th:text="#{label.title}">제목</label> <label for="content" th:text="#{label.content}">내용</label>- 버튼에 적용지금까지 메시지를 효율적으로 관리하는 방법을 알아보았다. 이제 여기에 더해서 국제화를 웹 애플리케이션에 어떻게 적용하는지 알아보자.이번에는 게시판에 국제화를 적용해보자. 먼저 영어 메시지를 추가하자.
messages_en.properties board.main=Board Main Page- ⭐️ 국제화
<button type="submit" class="btn" id="submitButton" th:text="#{button.write}">작성하기</button>
label.title=Title
label.author=Author
label.content=Content
label.imageFile=Image File
label.createdDate=Create Date
label.modifiedDate=Modified Date
label.search=Search Word:
page.write=Post Write
page.list=Post List
page.modified=Post Update
button.write=Post Write
button.delete=Post Delete
button.modified=Post Update
button.list=Post List
button.search=Search
나의 조잡한 영어로 대충 작성한 영어 버전의 메시지이다. 사실 이것으로 국제화 작업은 거의 끝났다. 앞에서 템플릿 파일에는 모두 `#{...}`를 통해서 메시지를 사용하도록 적용해두었기 때문이다.
- - -
**웹으로 확인하기**
웹 브라우저의 언어 설정 값을 변경하면서 국제화 적용을 확인해보자.
크롬 브라우저 -> 설정 -> 언어를 검색하고, 우선 순위를 영어가 처음에 오도록 하면 된다.
- - -
**언어 변경 전**

- - -
**언어 변경 후**

국제화가 적용 된 것이 보인다.
- - -
웹 브라우저의 언어 설정 값을 변경하면 요청시 `Accept-Language`의 값이 변경된다.
`Accept-Language`는 클라이언트가 서버에 기대하는 언어 정보를 담아서 요청하는 HTTP 요청 헤더이다.
**스프링의 국제화 메시지 선택**
메시지 기능은 Locale 정보를 알아야 언어를 선택할 수 있다.
결국 스프링도 Locale 정보를 알아야 언어를 선택할 수 있는데, **스프링은 언어 선택시 기본으로 Accept-Language 헤더의 값을 사용한다.**
**LocaleResolver**
스프링은 Locale 선택 방식을 변경할 수 있도록 **LocaleResolver 라는 인터페이스**를 제공하는데, 스프링 부트는 기본으로 Accept-Language 를 활용하는 **AcceptHeaderLocaleResolver** 를 사용한다.
LocaleResolver 인터페이스
```java
public interface LocaleResolver {
Locale resolveLocale(HttpServletRequest request);
void setLocale(HttpServletRequest request, @Nullable HttpServletResponse
response, @Nullable Locale locale);
}
LocaleResolver 변경
만약 Locale 선택 방식을 변경하려면 LocaleResolver의 구현체를 변경해서 쿠키나 세션 기반의 Locale 선택 기능을 사용할 수 있다. 예를 들어서 고객이 직접 Locale 을 선택하도록 하는 것이다.
관련해서 LocaleResolver를 검색하면 수 많은 예제가 나오니 필요한 분들은 참고하자.
더 자세한 코드는 깃허브를 참고해주세요!
Github: https://github.com/pp8817/ToyProjectBoard
'Project > 나의 작은 프로젝트' 카테고리의 다른 글
| 💡 게시판 - 검증(Bean Validation) (0) | 2026.07.21 |
|---|---|
| 💡 게시판 - 파일 다운로드 (1) | 2026.07.20 |
| 💡 게시판 - 파일 업로드 3(개선) (0) | 2026.07.20 |
| 💡 게시판 - 파일 업로드 2 (0) | 2026.07.20 |
| 💡 게시판 - 파일 업로드 (0) | 2026.07.20 |