02.ETC

ETC

λ©”μ‹œμ§€, κ΅­μ œν™”

λ©”μ‹œμ§€ κΈ°λŠ₯: λ‹€μ–‘ν•œ λ©”μ‹œμ§€λ₯Ό ν•œ κ³³μ—μ„œ κ΄€λ¦¬ν•˜λŠ” κΈ°λŠ₯

messages.properteis

item=μƒν’ˆ
item.id=μƒν’ˆ ID
item.itemName=μƒν’ˆλͺ…
item.price=가격
item.quantity=μˆ˜λŸ‰

κ΅­μ œν™” κΈ°λŠ₯: λ©”μ‹œμ§€ νŒŒμΌμ„ 각 λ‚˜λΌλ³„λ‘œ λ³„λ„λ‘œ κ΄€λ¦¬ν•˜λŠ” κ΅­μ œν™” κΈ°λŠ₯

  • messages_en.properties 와 같이 파일λͺ… λ§ˆμ§€λ§‰μ— μ–Έμ–΄ 정보 μΆ”κ°€

  • 찾을 수 μžˆλŠ” κ΅­μ œν™” 파일이 μ—†μœΌλ©΄ messages.properties λ₯Ό 기본으둜 μ‚¬μš©

messages_en.propertis

item=Item
item.id=Item ID
item.itemName=Item Name
item.price=price
item.quantity=quantity

messages_ko.propertis

Spring Message Source

SpringBoot λŠ” MessageSource λ₯Ό μžλ™μœΌλ‘œ μŠ€ν”„λ§ 빈으둜 등둝

  • Spring μ‚¬μš© μ‹œ κ΅¬ν˜„μ²΄μΈ ResourceBundleMessageSource λ₯Ό 빈으둜 등둝

SpringBoot Message Source μ„€μ •

application.properties

  • μŠ€ν”„λ§ λΆ€νŠΈ λ©”μ‹œμ§€ μ†ŒμŠ€ κΈ°λ³Έ κ°’: spring.messages.basename=messages

  • MessageSource λ₯Ό μŠ€ν”„λ§ 빈 λ“±λ‘ν•˜μ§€ μ•Šκ³ , μŠ€ν”„λ§ λΆ€νŠΈ κ΄€λ ¨ 섀정을 ν•˜μ§€ μ•ŠμœΌλ©΄ messages λΌλŠ” μ΄λ¦„μœΌλ‘œ κΈ°λ³Έ 등둝

  • λ”°λΌμ„œ messages.properties, messages_en.properties .. 파일만 λ“±λ‘ν•˜λ©΄ μžλ™μœΌλ‘œ 인식

  • μΆ”κ°€ μ˜΅μ…˜μ€ Spring-Boot Docsarrow-up-right μ°Έκ³ 

  • /resources/messages.properties κ²½λ‘œμ— Message 파일 μ €μž₯

Message Source μ‚¬μš©

  • SpringBoot λŠ” MessageSource λ₯Ό μžλ™μœΌλ‘œ Spring Bean 으둜 λ“±λ‘ν•˜λ―€λ‘œ λ°”λ‘œ μ‚¬μš© κ°€λŠ₯

  • MessageSource λŠ” message.properties 파일 정보λ₯Ό κ°€μ§€κ³  있음

Message Source κ΅­μ œν™” μ‚¬μš©

  • locale 정보 기반으둜 κ΅­μ œν™” 파일 선택

  • Locale 이 en_US 일 경우 messages_en_US ➜ messages_en ➜ messages(default) μˆœμ„œ 탐색

Web Application Message

λ©”μ‹œμ§€ 적용

  • νƒ€μž„λ¦¬ν”„μ˜ λ©”μ‹œμ§€ ν‘œν˜„μ‹ #{...} λ₯Ό μ‚¬μš©ν•˜λ©΄ μŠ€ν”„λ§ λ©”μ‹œμ§€λ₯Ό νŽΈλ¦¬ν•˜κ²Œ 쑰회 κ°€λŠ₯

    • messages.properties

    • Thymeleaf

κ΅­μ œν™” 적용

  • μ›Ή λΈŒλΌμš°μ €μ˜ μ–Έμ–΄ μ„€μ • 값이 λ³€ν•˜λ©΄ μš”μ²­μ‹œ Accept-Language 의 값이 λ³€κ²½λ˜κ³ , 이 정보λ₯Ό Spring 은 Locale 둜 인식해 μžλ™μœΌλ‘œ κ΅­μ œν™” 처리

  • LocaleResolver

    • Spring 은 Locale 선택 방식을 λ³€κ²½ν•  수 μžˆλ„λ‘ LocaleResolver μΈν„°νŽ˜μ΄μŠ€ 제곡

    • Spring Boot λŠ” μ–Έμ–΄ 선택 μ‹œ 기본적으둜 Accept-Language 헀더값을 ν™œμš©ν•˜λŠ” AcceptHeaderLocaleResolver μ‚¬μš©

    • Locale 선택 방식을 λ³€κ²½ν•˜λ €λ©΄ LocaleResolver κ΅¬ν˜„μ²΄λ₯Ό λ³€κ²½ν•΄μ„œ μΏ ν‚€λ‚˜ μ„Έμ…˜ 기반의 Locale 선택 κΈ°λŠ₯ μ‚¬μš©


Spring Type Converter

μŠ€ν”„λ§ νƒ€μž… λ³€ν™˜ 적용 예

  • HTTP Query String 으둜 μ „λ‹¬λ˜λŠ” λ°μ΄ν„°λŠ” λͺ¨λ‘ String Type μ΄μ§€λ§Œ, μŠ€ν”„λ§μ€ νƒ€μž…μ„ λ³€ν™˜ν•΄ 제곡

    • @RequestParam

    • @ModelAttribute

    • @PathVariable

    • @Value

    • XML Spring Bean 정보 λ³€ν™˜

    • View Rendering

    • ...

Type Converter

Converter Interface

μŠ€ν”„λ§μ— μ‚¬μš©μž μ •μ˜ νƒ€μž… λ³€ν™˜μ΄ ν•„μš”ν•˜λ©΄ 컨버터 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ„œ 등둝해 보자.

ex. 컨버터 μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„

  • μŠ€ν”„λ§μ€ μš©λ„μ— 따라 λ‹€μ–‘ν•œ λ°©μ‹μ˜ νƒ€μž… 컨버터 제곡

    • Converter : κΈ°λ³Έ νƒ€μž… 컨버터

    • ConverterFactory : 전체 클래슀 계측 ꡬ쑰가 ν•„μš”ν•  경우

    • GenericConverter : μ •κ΅ν•œ κ΅¬ν˜„, λŒ€μƒ ν•„λ“œμ˜ μ• λ…Έν…Œμ΄μ…˜ 정보 μ‚¬μš© κ°€λŠ₯

    • ConditionalGenericConverter : νŠΉμ • 쑰건이 참인 κ²½μš°μ—λ§Œ μ‹€ν–‰

    • 그밖에 문자, 숫자, boolean, Enum λ“± 일반적인 νƒ€μž…μ— λŒ€ν•œ λŒ€λΆ€λΆ„μ˜ 컨버터λ₯Ό 기본으둜 제곡

Spring Type Conversionarrow-up-right

ConversionService

κ°œλ³„ 컨버터λ₯Ό λͺ¨μ•„두고, 그것듀을 λ¬Άμ–΄μ„œ νŽΈλ¦¬ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλŠ” κΈ°λŠ₯

  • μŠ€ν”„λ§μ€ @RequestParam 같은 κ³³ λ‚΄λΆ€μ—μ„œ ConversionService λ₯Ό μ‚¬μš©ν•΄μ„œ νƒ€μž…μ„ λ³€ν™˜

ConversionService interface

  • Converting κ°€λŠ₯ 여뢀와 κΈ°λŠ₯ 제곡

DefaultConversionService

  • ConversionService μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄(컨버터λ₯Ό λ“±λ‘ν•˜λŠ” κΈ°λŠ₯도 제곡)

  • μ‚¬μš© 초점의 ConversionService 와 등둝 초점의 ConverterRegistry 둜 λΆ„λ¦¬λ˜μ–΄ κ΅¬ν˜„

    • μΈν„°νŽ˜μ΄μŠ€ 뢄리 원칙 적용(ISP-Interface Segregation Principal)

    • μΈν„°νŽ˜μ΄μŠ€ 뢄리λ₯Ό 톡해 컨버터λ₯Ό μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ 컨버터λ₯Ό λ“±λ‘ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 관심사λ₯Ό λͺ…ν™•ν•˜κ²Œ 뢄리

.

  • νƒ€μž… 컨버터듀은 컨버전 μ„œλΉ„μŠ€ 내뢀에 μˆ¨μ–΄μ„œ μ œκ³΅λ˜λ―€λ‘œ, ν΄λΌμ΄μ–ΈνŠΈλŠ” νƒ€μž… 컨버터λ₯Ό λͺ°λΌλ„ 무관

  • νƒ€μž… λ³€ν™˜μ„ μ›ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 경우 컨버전 μ„œλΉ„μŠ€ μΈν„°νŽ˜μ΄μŠ€μ—λ§Œ 의쑴

    • 컨버전 μ„œλΉ„μŠ€λ₯Ό λ“±λ‘ν•˜λŠ” λΆ€λΆ„κ³Ό μ‚¬μš©ν•˜λŠ” 뢀뢄을 λΆ„λ¦¬ν•˜κ³  μ˜μ‘΄κ΄€κ³„ μ£Όμž…μ„ μ‚¬μš©

Apply Converter in Spring 🌞

  • μŠ€ν”„λ§μ€ λ‚΄λΆ€μ—μ„œ ConversionService 제곡

  • WebMvcConfigurer κ°€ μ œκ³΅ν•˜λŠ” addFormatters() λ₯Ό μ‚¬μš©ν•΄μ„œ 컨버터 등둝

  • @RequestParam 의 경우 RequestParamMethodArgumentResolver μ—μ„œ ConversionService λ₯Ό μ‚¬μš©ν•΄μ„œ νƒ€μž…μ„ λ³€ν™˜

WebConfig.java

Apply Converter in View Template

νƒ€μž„λ¦¬ν”„λŠ” λ Œλ”λ§ μ‹œ 컨버터λ₯Ό μ μš©ν•΄μ„œ λ Œλ”λ§ ν•˜λŠ” 방법을 νŽΈλ¦¬ν•˜κ²Œ 지원

View Template

Controller.java

view.html

  • λ³€μˆ˜ ν‘œν˜„μ‹ : ${...}

  • 컨버전 μ„œλΉ„μŠ€ 적용 : ${{...}}

Form

Controller.java

  • @ModelAttribute λ‚΄λΆ€μ—μ„œ ConversionService λ™μž‘

form.html

  • th:field λŠ” Converter κΉŒμ§€ μžλ™ 적용

  • th:value λŠ” λ³΄μ—¬μ£ΌλŠ” μš©λ„

Formatter

객체λ₯Ό νŠΉμ •ν•œ 포멧에 λ§žμΆ”μ–΄ 문자둜 좜λ ₯ν•˜κ±°λ‚˜, κ·Έ λ°˜λŒ€μ˜ 역할을 ν•˜λŠ” 것에 νŠΉν™”λœ κΈ°λŠ₯

  • Converter: λ²”μš©(객체 ➜ 객체)에 μ‚¬μš©

  • Formatter: 문자(객체 ➜ 문자, 문자 ➜ 객체, ν˜„μ§€ν™”)에 νŠΉν™”

    • νŠΉλ³„ν•œ Converter..

Formatter Interface

implements Formatter

μŠ€ν”„λ§μ€ μš©λ„μ— 따라 λ‹€μ–‘ν•œ λ°©μ‹μ˜ 포맷터 제곡

  • AnnotationFormatterFactory: ν•„λ“œμ˜ νƒ€μž…μ΄λ‚˜ μ• λ…Έν…Œμ΄μ…˜ 정보λ₯Ό ν™œμš©ν•  수 μžˆλŠ” 포맷터

FormattingConversionService

  • ConverstionService μ—λŠ” μ»¨λ²„ν„°λ§Œ 등둝 κ°€λŠ₯ν•˜κ³ , ν¬λ§·ν„°λŠ” 등둝 λΆˆκ°€

  • 포맷터 등둝을 μ§€μ›ν•˜λŠ” FormattingConversionService λ₯Ό μ‚¬μš©ν•˜μ—¬ 포맷터λ₯Ό μΆ”κ°€ν•΄ 보자.

    • λ‚΄λΆ€μ—μ„œ μ–΄λŒ‘ν„° νŒ¨ν„΄μ„ μ‚¬μš©ν•΄μ„œ Formatter κ°€ Converter 처럼 λ™μž‘ν•˜λ„λ‘ 지원

  • DefaultFormattingConversionService λŠ” FormattingConversionService λ₯Ό 상속받아 기본적인 톡화, 숫자 κ΄€λ ¨ κΈ°λ³Έ 포맷터λ₯Ό μΆ”κ°€ 제곡

    • ConversionService κ΄€λ ¨ κΈ°λŠ₯을 μƒμ†λ°›μœΌλ―€λ‘œ Converter, Formatter λͺ¨λ‘ 등둝 κ°€λŠ₯

  • μŠ€ν”„λ§ λΆ€νŠΈλŠ” DefaultFormattingConversionService λ₯Ό 상속 받은 WebConversionService λ₯Ό λ‚΄λΆ€μ—μ„œ μ‚¬μš©

Apply Formatter in Spring 🌞

  • κΈ°λŠ₯이 κ²ΉμΉ  경우(Source-type, Target-type 동일) Converter μš°μ„ 

Annotation driven Formatting

  • μŠ€ν”„λ§μ€ μžλ°”μ—μ„œ 기본으둜 μ œκ³΅ν•˜λŠ” νƒ€μž…λ“€μ— λŒ€ν•΄ μˆ˜λ§Žμ€ 포맷터λ₯Ό 기본으둜 제곡

  • 객체의 각 ν•„λ“œλ§ˆλ‹€ λ‹€λ₯Έ ν˜•μ‹μ˜ 포맷을 μ§€μ •ν•˜λŠ” 어렀움을 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ• λ…Έν…Œμ΄μ…˜ 기반 ν˜•μ‹ μ§€μ • 포맷터 제곡

    • @NumberFormat : 숫자 κ΄€λ ¨ ν˜•μ‹ μ§€μ • 포맷터 μ‚¬μš©

      • NumberFormatAnnotationFormatterFactory

    • @DateTimeFormat : λ‚ μ§œ κ΄€λ ¨ ν˜•μ‹ μ§€μ • 포맷터 μ‚¬μš©

      • Jsr310DateTimeFormatAnnotationFormatterFactory

Annotation-driven Formattingarrow-up-right

μ°Έκ³ ,

HttpMessageConverter μ—λŠ” Convetion Service κ°€ μ μš©λ˜μ§€ μ•ŠμŒ

JSON 을 객체둜 λ³€ν™˜ν•˜λŠ” HttpMessageConverter λŠ” λ‚΄λΆ€μ—μ„œ Jackson 같은 라이브러리λ₯Ό μ‚¬μš©

λ”°λΌμ„œ, JSON 결과둜 λ§Œλ“€μ–΄μ§€λŠ” μˆ«μžλ‚˜ λ‚ μ§œ 포맷을 λ³€κ²½ν•˜κ³  μ‹ΆμœΌλ©΄ ν•΄λ‹Ή λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ œκ³΅ν•˜λŠ” 섀정을 ν†΅ν•΄μ„œ 포맷을 μ§€μ •

File Upload

전솑 방식

기본적인 HTML Form 전솑 방식

  • application/x-www-form-urlencoded

  • HTML Form

  • HTTP Message

Form λ‚΄μš©κ³Ό μ—¬λŸ¬ νŒŒμΌμ„ ν•¨κ»˜ μ „μ†‘ν•˜λŠ” HTML Form 전솑 방식

  • multipart/form-data

  • HTML Form

    • form tag 에 enctype="multipart/form-data" μ§€μ •

  • HTTP Message

    • 각각의 전솑 ν•­λͺ©μ΄ ꡬ뢄

    • Content-Disposition λΌλŠ” ν•­λͺ©λ³„ 헀더와 λΆ€κ°€ 정보가 뢄리

HTTP λ©”μ‹œμ§€ μ°Έκ³ arrow-up-right

Servlet File Upload

Multipart κ΄€λ ¨ μ„€μ •

  • multipart.enabled μ˜΅μ…˜μ΄ 켜져 μžˆλ‹€λ©΄, Spring DispatcherServlet μ—μ„œ MultipartResolver μ‹€ν–‰

  • multipart μš”μ²­μΈ 경우 Servlet Container κ°€ μ „λ‹¬ν•˜λŠ” HttpServletRequest λ₯Ό MultipartHttpServletRequest 둜 λ³€ν™˜ν•΄μ„œ λ°˜ν™˜

  • Spring 이 μ œκ³΅ν•˜λŠ” κΈ°λ³Έ MultipartResolver λŠ” MultipartHttpServletRequest Interface λ₯Ό κ΅¬ν˜„ν•œ StandardMultipartHttpServletRequest λ₯Ό λ°˜ν™˜

ServletUploadController.java

Spring File Upload 🌞

  • μŠ€ν”„λ§μ€ MultipartFile Interface 둜 Multipart File 을 맀우 νŽΈλ¦¬ν•˜κ²Œ 지원

File Upload And Download

예제둜 κ΅¬ν˜„ν•˜λŠ” 파일 μ—…λ‘œλ“œ, λ‹€μš΄λ‘œλ“œ (1)arrow-up-right

예제둜 κ΅¬ν˜„ν•˜λŠ” 파일 μ—…λ‘œλ“œ, λ‹€μš΄λ‘œλ“œ (2)arrow-up-right

Last updated