πŸ’‘ κ²Œμ‹œνŒ - λ©”μ‹œμ§€, κ΅­μ œν™”

박상민·2023λ…„ 9μ›” 21일
0

✏️ λ©”μ‹œμ§€, κ΅­μ œν™” 글을 μž‘μ„±ν–ˆλ‹€.
μ΄λ²ˆμ—λŠ” λ‚΄κ°€ λ§Œλ“€λ˜ κ²Œμ‹œνŒμ— λ©”μ‹œμ§€, κ΅­μ œν™”λ₯Ό μ μš©ν•˜λ € ν•œλ‹€.
사싀 λ‚˜μ˜ κ²Œμ‹œνŒμ€ ν•΄μ™Έ μ‚¬λžŒμ΄ μ‚¬μš©ν•  일이 μ—†κΈ° λ•Œλ¬Έμ— κ΅­μ œν™”λ₯Ό ν•  ν•„μš”κ°€ μ—†λ‹€. κ·ΈλŸ¬λ‚˜ 곡뢀 μ°¨μ›μ—μ„œ μ μš©ν•˜λ €κ³  ν•œλ‹€.

⭐️ λ©”μ‹œμ§€

λ¨Ό λ©”μ‹œμ§€λ₯Ό μΆ”κ°€ λ“±λ‘ν•˜μž.

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>
  • λ²„νŠΌμ— 적용
<button type="submit" class="btn" id="submitButton" th:text="#{button.write}">μž‘μ„±ν•˜κΈ°</button>

μ§€κΈˆκΉŒμ§€ λ©”μ‹œμ§€λ₯Ό 효율적으둜 κ΄€λ¦¬ν•˜λŠ” 방법을 μ•Œμ•„λ³΄μ•˜λ‹€. 이제 여기에 λ”ν•΄μ„œ κ΅­μ œν™”λ₯Ό μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μ–΄λ–»κ²Œ μ μš©ν•˜λŠ”μ§€ μ•Œμ•„λ³΄μž.

⭐️ κ΅­μ œν™”

μ΄λ²ˆμ—λŠ” κ²Œμ‹œνŒμ— κ΅­μ œν™”λ₯Ό μ μš©ν•΄λ³΄μž. λ¨Όμ € μ˜μ–΄ λ©”μ‹œμ§€λ₯Ό μΆ”κ°€ν•˜μž.
messages_en.properties

board.main=Board Main Page

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 μΈν„°νŽ˜μ΄μŠ€

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


좜처
(κ°•μ˜)μŠ€ν”„λ§ MVC 2편 - λ°±μ—”λ“œ μ›Ή 개발 ν™œμš© 기술

profile
μŠ€ν”„λ§ λ°±μ—”λ“œλ₯Ό 곡뢀쀑인 λŒ€ν•™μƒμž…λ‹ˆλ‹€!

0개의 λŒ“κΈ€