背景
業務でAPIのエラーレスポンスのメッセージを多言語で返したかったので試してみました。
project作成
いつも通りSpring Initializrでprojectを作ります。
https://start.spring.io/
messages.propertiesの作成
MessageSourceConfigの作成
@Configuration
class MessageSourceConfig {
@Bean
fun messageSource(): MessageSource {
val messageSource = ResourceBundleMessageSource()
messageSource.setBasenames("i18n/messages")
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name())
messageSource.setFallbackToSystemLocale(false)
return messageSource
}
}
resourceファイルの指定と、デフォルトEncode設定や、
未設定のLocaleが来たときのデフォルト設定のためにConfigファイルを作成します。
Conrtollerの作成
@RestController
@RequestMapping("hoge")
class HogeController {
@Autowired
lateinit var messageSource: MessageSource
@GetMapping("message")
fun getMessage(locale: Locale): ResponseEntity<String> {
val errorMsg = messageSource.getMessage("hoge", null, locale)
return ResponseEntity.ok(errorMsg)
}
@GetMapping("exception")
fun getException(): ResponseEntity<String> {
// コンパイルを通すためにif分を挟む
if (true) {
throw DataNotFoundException()
}
return ResponseEntity.ok("")
}
}
通常とExceptionをThrowするパターンを作っておきます。
通常のエンドポイントでmessageが取得できることを確認します。
まずはjaで叩いてみます。
ちゃんと日本語で返ってきましたね!!
次にenで叩いてみます。
こちらもちゃんと英語で返ってきてますね!!
未作成のkoで叩いてみます。
setFallbackToSystemLocaleの設定が効いているので英語で返ってきてますね!
エラーレスポンス用のExceptionHandlerの作成
@RestControllerAdvice
class ExceptionHandler {
@Autowired
lateinit var messageSource: MessageSource
@ExceptionHandler(DataNotFoundException::class)
fun handleDataNotFoundException(e: DataNotFoundException, locale: Locale): ResponseEntity<String> {
val errorMsg = messageSource.getMessage("dataNotFound", null, locale)
return ResponseEntity(errorMsg, HttpStatus.NOT_FOUND)
}
}
ExcrptionをCatchしてエラーレスポンスを返すためにHandlerを作ります。
作成後、Excptionをthrowするエンドポイントを叩き、messageが取得できることを確認します。
通常と同様、ja, en koで叩いてみます。
終わりに
以上で、Springでエラーレスポンスを多言語化してみました。
フロントによってはAPIのレスポンスメッセージをそのまま出す場合があるのでサーバ側でいい感じにできると嬉しいですね。
サンプルソース
https://github.com/akawai11/spring-message-source-sample