Hello

spring 다국어 지원을 위한 설정 본문

spring

spring 다국어 지원을 위한 설정

nari0_0 2023. 3. 3. 16:57
728x90

하..다썻는데..날라갔다 진짜 하기싫다 인생사 왜 임시저장도 안되있냐 진짜 다시 해야하냐

LocaleResolver

request를 통한 locale 확인과 request,response를 통한 locale 수정을 모두 허용하는 웹 기반 lcoale 확인 전략용 인터페이스

request, session, cookie 등 기반한 구현을 허용합니다. 기본 구현은 Acc

RequestContext.getLocale() 실제 해결 전략과 관계없이 현재 locale 값 확인 가능하다.

spring4 부터 LocaleContextResolver 이 추가 되어 Locale 및 Timezone 정보 지원이 가능합니다.

 

- AcceptHeaderLocaleResolver

브라우저에 설정된 language 정보를 사용한다.

LocaleResolver을 구현하고 있다. setLocale()호출시 아래 exception을 발생시킨다.

@Bean
    public LocaleResolver localeResolver() {
        return new AcceptHeaderLocaleResolver();
    }
@Override
	public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {
		throw new UnsupportedOperationException(
				"Cannot change HTTP accept header - use a different locale resolution strategy");
	}

 

- CookieLocaleResolver

쿠키에 locale 정보를 저장해 두고 사용한다.

쿠키관련 여러 설정이 있다. 필요한 설정은 확인해서 사용하면 될 것 같다

@Bean
    public LocaleResolver localeResolver() {
    	CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        cookieLocaleResolver.setCookieName("lang");
        cookieLocaleResolver.setDefaultLocale(Locale.KOREA);
        return cookieLocaleResolver;
    }

 

- FixedLocaleResolver

어떤 언어가 넘어오더라도 고정된 Locale 만을 지원한다.

AbstractLocaleContextResolver을 상속하고 있다. setLocale()호출시 AbstractLocaleContextResolver내부적으로 아래 setLocaleContext()메소드를 호출한다 아래 exception을 발생시킨다.

 

@Bean
    public LocaleResolver localeResolver() {
        return new FixedLocaleResolver(Locale.ENGLISH);
    }
@Override
	public void setLocaleContext( HttpServletRequest request, @Nullable HttpServletResponse response,
			@Nullable LocaleContext localeContext) {
		throw new UnsupportedOperationException("Cannot change fixed locale - use a different locale resolution strategy");
	}

 

SessionLocaleResolver

-세션에 locale 정보를 저장해 두고 사용한다.

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
        sessionLocaleResolver.setDefaultLocale(Locale.KOREA);
        return sessionLocaleResolver;
    }

 

LocaleChangeInterceptor

구성 가능한 요청 매개변수(기본 매개변수 이름: "locale")를 통해 모든 요청에서 locale 을 변경할 수 있는 인터셉터.

url의 query parameter에 locale 인자값을 받아 변경한다. ex)home?lang=ko

 

spring 5 사용 시 WebMvcconfigurer.addInterceptors 에 인터셉터를 등록해 사용가능하다.

아래처럼 등록시 모든 요청에 LocaleChangeInterceptor이 호출된다.

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}

controller에서 locale변경하는방법

html 에서 select box를 활용해 언어를 바꾸고자 하는경우 사용할 수 있는 방법이다.

spring docs에서는 session과 cookie local resolver 구현체에서 locale변경할 때 RequestContext.changeLocale 사용할 것을 제안하고 있다.

이 방법을 사용하면, session, cookie 방법에 따라 구현 내용이 달라지지 않는다b.

RequestContext.changeLocale 내부적으로 localeResolver.setLocale 를 호출한다. 빈으로 올라간 LocaleResolver구현체의 메소드 호출 session, cookie 모두 변경 되는 것을 확인했다.

    @GetMapping("/lang")
    public void changeLocale(String lang, HttpServletRequest request, HttpServletResponse response) {
        RequestContext requestContext = new RequestContext(request,response);
        requestContext.changeLocale(new Locale(lang));
    }

messages.properties

파일명은 message_언어코드.properties 형태로 만든다

인텔리저이는 여러개의 messages.properties를 만들경우 이미지의 왼쪽과 같이 번들로 묶어주며 중앙, 오른쪽에서 각 키값의 매핑되는 값을 보여준다.

MessageSource빈을 등록해 message.properties를 사용할 수 있습니다.

basename의 기본경로 /src/main/resources

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
        resourceBundleMessageSource.setBasename("messages");
        resourceBundleMessageSource.setDefaultEncoding("UTF-8");
        return resourceBundleMessageSource;
    }

언어별로 에러 메시지를 달리해야한다면, 에러코드를 작성해두고 사용할 수 있다.

RequestContext requestContext = new RequestContext(request,response);
Locale locale = requestContext.getLocale();
throw new RuntimeException(messageSource.getMessage("not_found", new String[]{},locale));

 

Freemarker에서 사용하는 방법

html에서 메시지를 사용하려면 스프링 매크로를 가져와야 합니다.

<#import "/spring.ftl" as spring/>

 

메시지는 <@spring.message "message_key"/> 구문을 사용해 .ftl 내에서 액세스할 수 있습니다.

 

 

참고 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/i18n/package-summary.html

https://oingdaddy.tistory.com/363

https://stackoverflow.com/questions/26459625/how-to-load-lables-via-properties-file-in-freemarker

728x90