Backend/Spring

스프링의 메시지 기능(MessageSource)

olsohee 2024. 1. 11. 15:57

MessageSource

메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource를 사용하면 된다. MessageSource는 다음과 같이 인터페이스 형태이다.

public interface MessageSource {

	@Nullable
	String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

	String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;

	String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

}

MessageSource 구현체를 스프링 빈으로 등록

메시지 관리 기능을 사용하려면 다음과 같이 MessageSource를 구현한 구현체를 스프링 빈으로 등록하면 된다.

@Bean
public MessageSource messageSource() {
         
	ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
	messageSource.setBasenames("messages", "errors"); 
	messageSource.setDefaultEncoding("utf-8");
	return messageSource;
}
  • setBasenames(): 메시지 설정 파일의 이름을 지정한다. 위 예제와 같이 여러 파일("message", "errors")을 지정할 수도 있다. 
  • setDefaultEncoding(): 인코딩 정보를 지정한다.

MessageSource 자동 등록

그런데 스프링 부트는 MessageSource 인터페이스를 자동으로 스프링 빈으로 등록한다. 스프링 부트는 application.yml의 정보를 참고해서 MessageSource가 참고할 메시지 설정 파일 인식한다.

 

따라서 스프링 부트를 사용한다면 MessageSource 구현체를 스프링 빈으로 수동 등록해주지 않아도 되고, 다음과 같이 application.yml에 메시지 설정 파일을 지정해주면 된다. 

spring:
  messages:
    basename: errors

 

참고로 스프링 부트가 자동 등록하는 MessageSource 구현체는 ResourceBundleMessageSource이다. (MessageSourceAutoConfiguration 클래스 참고)

예제

수동으로 등록했든 스프링이 자동으로 application.yml 파일을 기반으로 등록했든 MessageSource는 스프링 빈으로 등록되어 있기 때문에 다음과 같이 @Autowired로 주입받아서 사용하면 된다.

@RestControllerAdvice
@AllArgsConstructor
public class ExceptionController {

    private final MessageSource messageSource;

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleBeanValidationError(MethodArgumentNotValidException e) {

        // 예외에 대한 오류 코드(MessageCodesResolver가 생성)
        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
        String code = objectError.getCodes()[0];
        
        // errors 파일에서 오류 코드에 맞는 메시지 찾아오기
        String message1 = messageSource.getMessage(code, null, null);
        String message2 = messageSource.getMessage("xxx", null, "기본 오류 메시지", null);
        
        return new ErrorResponse(HttpStatus.BAD_REQUEST, message1);
    }
}
  • MessageSource.getMessage() 메소드의 파라미터는 다음과 같다.
    • code: 메시지 설정 파일에 해당 code 값에 해당하는 메시지가 반환된다.
    • args: code에 해당하는 메시지에 치환되는 값이다.
    • defaultMessage: code에 해당되는 오류 코드(메시지)를 찾지 못했을 때 반환되는 값이다. 조회되는 메시지가 없는 경우에는 NoSuchMessageException이 발생하고, 조회되는 메시지가 없는데 defaultMessage를 설정했으면 defaultMessage가 반환된다.
    • locale: 언어 정보이다. locale 정보가 없으면 basename에서 설정한 기본 이름의 메시지 설정 파일을 조회한다. 

Reference