Spring발행일 2025. 1. 14.원본 https://blog.naver.com/jword_/223725795452 ↗

Spring에서 다국어 처리를 해보자

Spring에서 다국어 처리를 해보자 — #개발자의도구들 #Spring다국어처리 AI스쿨 msa기반 java 백엔드 코스 중에 공부한 내용을 작성하였습니...

#Spring#Naver Blog

#개발자의도구들 #Spring다국어처리

​

AI스쿨 msa기반 java 백엔드 코스 중에 공부한 내용을 작성하였습니다

\* 현재 Spring x 프로젝트를 진행하고 있습니다. 전체 목차를 보시려면 여기를 눌러주세요.

\* 해당 프로젝트 이전에 공부한 내용을 보시려면 여기를 눌러주세요.

​

다국어 처리 기본 개념

글로벌 서비스를 지원하는 서버라면 그 나라의 언어에 맞는 데이터를 보낼 필요가 있다. 특히 영어와 한국어처럼 언어의 어순이 다른 경우라면 더욱 신경써서 메세지를 보내야한다.

​

이런 처리를 하기 위한 가장 기본적인 개념은 HTTP Request 헤더에 언어에 대한 정보를 넣는 것이다. HTTP헤더에는 언어를 넣는 다양한 방법들이 있는데, 기본적으로 Request 헤더의 Accept-Language 필드에 넣으면 된다.

​

언어를 넣는 방법도 다양하다. 우선 언어를 어떻게 넣으면 좋을지 생각해보자. 우선 영어가 사용될 것이고, 특정 단어들이 사용될 것이다. 예를들면 한국어 Korea 영어 English 등 이런식으로 넣을 수 있다. 하지만 여기서 사용되는 언어는 언어코드라는 것을 사용한다.

​

언어코드는 두 글자 코드, 세 글자 코드가 존재한다. 보통 두 글자 코드를 많이 사용하며, 애플의 경우 세 글자 코드를 선호한다고 알려져 있다.

그럼 서버는 HTTP 헤더의 해당 필드를 읽어들여 해당 클라이언트에게 어떤 언어 메세지를 만들어 보내야할지 알 수 있다.

서버가 메세지를 만드는 방법

이제 서버가 언어에 대한 정보를 알고있다. 그럼 어떻게 메세지를 보내야할까?

​

일단 기본적으로 다국어의 경우 Noti Api와 연동된다. 이전글에서 보다싶이 서버는 MSA 서버로 부터 전달받은 key값을 통해 메세지를 조합해서 최종적으로 클라이언트에게 메세지를 전송한다. 이 과정에서 언어에 따라 만들어지는 메세지가 다를 것이다. 아래 예시를 보자.

javascript 코드 예제
                                    👉 팔로우 메세지를 보내는 경우

한국어: 00 님이 당신을 팔로우합니다.
영어 : you are followed by 00

이렇게 어순이 다르기 때문에 미리 메세지의 형식을 지정해두고, 00과 같은 변수만 받아서 메세지를 만들어 보내는게 좋다. 이를 위해서 서버는 Message Format을 사용한다.

Message Format을 사용하자

Message Format은 MessageSource와 .properties파일을 사용하여 메세지를 미리 만들어 둘 수 있는 기능을 제공한다.

​

우선 MessageSource를 빈으로 등록하여 커스텀 옵션을 만든다.

javascript 코드 예제
                                    @Configuration
class MessageConfig {
    @Bean
    fun messageSource(): MessageSource {
        val messageSource = ReloadableResourceBundleMessageSource()
        messageSource.setBasename("classpath:messages") // messages.properties의 file 경로
        messageSource.setDefaultEncoding("UTF-8")
        messageSource.setUseCodeAsDefaultMessage(true)
        messageSource.setCacheSeconds(1)
        return messageSource
    }
}

이후 각 언어별 properties파일을 만들면 된다. properties파일은 resource 폴더 내부에 만들면된다. (application.yaml or application.properties와 같은 위치)

💡 반드시 setBasename에 "classpath:messages"를 넣자.

파일: messages\_en.properties

  • 여기서 반드시 messages로 시작해야하며, 뒤의 언어는 언어 코드를 사용하면 된다.
javascript 코드 예제
                                    greeting=Hello!!

greeting을 지정하면 이것은 key값이 된다. 아래에서 다시 설명하겠다.

​

파일: messages\_ko.properties

javascript 코드 예제
                                    greeting=안녕하세요

자 이제 두개의 파일이 생성되었다. MessageSource는 en과 ko를 구분하고 greeting key에 해당하는 메세지를 출력할 것이다.

Spring에서 사용해보자

이제 실전이다. Controller에 간단한 api를 등록하고 greeting으로 지정한 메세지를 출력해보자.

javascript 코드 예제
                                    @RestController
class LangController(
    @Autowired
    private val messageSource: MessageSource
) {
    private val logger = KotlinLogging.logger {}

    @GetMapping("/lang")
    fun getGreeting(@RequestHeader(value = "Accept-Language", defaultValue = "en") language: String)
    : ResponseEntity<String> {
        logger.info { "language: $language" }
        val locale = Locale.forLanguageTag(language)
        logger.info { "locale: $locale" }
        logger.info {"message: ${messageSource.getMessage("greeting", null, locale) }"}
        return ResponseEntity.ok().body(
            messageSource.getMessage("greeting", null, locale)
        )
    }
}
  • Accept-Language 헤더 정보에서 language를 추출한다.
  • Locale은 해당 language를 통해 등록된 properties파일을 찾도록 한다.(두글자 언어코드를 지원한다.
  • 최종적으로 MessageSource에 greeting을 보내면 greeting을 key로 사용하여 미리 입력된 메세지가 출력된다.

변수를 사용하자

아직까지는 뭔가 아쉽다. 이유는 이전에 등록해 놓을건 해놓고, 변수로 넘길건 넘겨서 메세지를 만드는게 좋다라고 말했기 때문이다. 현재는 MessageSource에 아무런 변수를 넘기지 않아서 동적인 메세지가 만들어지지 않았다. 이번에는 변수를 넘기는 방법에 대해 알아보자.

​

간단하게 messages\_ko.properties를 수정하자.

javascript 코드 예제
                                    greeting=안녕하세요 {0}, {1}님!

properties에 {0}형태로 등록된게 바로 동적 메세지를 위한 변수이다. 여기서 정수가 들어가 있는 이유는 변수를 array형태로 넘기기 때문이며 이는 인덱스이다.

javascript 코드 예제
                                    return ResponseEntity.ok().body(
            messageSource.getMessage("greeting", arrayOf("TOD", "KIM"), locale)
        )

이렇게 두개의 변수를 넘기면 동적으로 메세지를 생성할 수 있다!

다양한 noti 메세지를 만들자

원론적인 부분이 끝나서 크게 추가할건 없다. noti 종류별 메세지를 어떻게 만들었는지만 정리했다.

javascript 코드 예제
                                    noti.LIKE :
-- ko : "${publisher}님이 ${board}게시글을 좋아합니다."
-- en : "User ${publisher} likse your poest: ${board}"

noti.board :
-- ko: "${publisher}님이 새 게시글을 등록하였습니다.\n"
       "${textContent}" (25자? 내외)
-- en: "${textContent} is poseted by ${publisher}"

noti.Follow:
-- ko : "${publisher}님이 당신을 팔로우 합니다."
-- en : "you are follwed by ${publisher}"

properties에 작성한건 아니고, 이런식으로 메세지에 이런 변수들이 들어가야한다는 것을 정리한 것이다.

​

관련 오류

properties의 인코딩을 변경해주자.

이미지

​