gpt4 book ai didi

Spring REST 处理语言环境更改

转载 作者:行者123 更新时间:2023-12-04 14:58:38 24 4
gpt4 key购买 nike

我正在尝试处理 Spring 3 REST 应用程序中的语言环境更改。

但是语言环境没有更改为 fr。

控制台日志显示:
2014-05-19 14:29:46,214 调试 [AbstractExceptionHandler] 语言环境:en

这是我的配置:

    @Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:messages/messages", "classpath:messages/validation");
// If true, the key of the message will be displayed if the key is not found, instead of throwing an exception
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
// The value 0 means always reload the messages to be developer friendly
messageSource.setCacheSeconds(0);
return messageSource;
}

// The locale interceptor provides a way to switch the language in any page just by passing the lang=’en’, lang=’fr’, and so on to the url
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}

@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(new Locale("en"));
return localeResolver;
}

这是我的异常处理程序:
@ControllerAdvice
public class AdminExceptionHandler extends AbstractExceptionHandler {

@ExceptionHandler(NullPointerException.class)
@ResponseBody
public ResponseEntity<ErrorInfo> nullPointerException(HttpServletRequest request, NullPointerException e) {
String url = request.getRequestURL().toString();
String errorMessage = localizeErrorMessage("error.npe", new Object[] { e.getMessage() });
return new ResponseEntity<ErrorInfo>(new ErrorInfo(url, errorMessage), HttpStatus.INTERNAL_SERVER_ERROR);
}

}

public class AbstractExceptionHandler {

private static Logger logger = LoggerFactory.getLogger(AbstractExceptionHandler.class);

@Autowired
private MessageSource messageSource;

protected String localizeErrorMessage(String errorCode, Object args[]) {
Locale locale = LocaleContextHolder.getLocale();
logger.debug("locale: " + locale);
return messageSource.getMessage(errorCode, args, locale);
}

protected String localizeErrorMessage(String errorCode) {
return localizeErrorMessage(errorCode, null);
}

protected String extractAdminIdFromUrl(String url) {
String adminId = null;
try {
URI uri = new URI(url);
String path = uri.getPath();
adminId = path.substring(path.lastIndexOf('/') + 1);
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
return adminId;
}

}

这是我的测试:
@Test
public void testExceptionLocalizedMessage() throws Exception {
HttpHeaders httpHeaders = Common.createAuthenticationHeaders("stephane" + ":" + PASSWORD);

MvcResult resultGet = this.mockMvc.perform(
get("/error/npe").headers(httpHeaders)
.param("lang", "fr")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.message").value("Une erreur inconnue s'est produite. Veuillez nous excuser."))
.andReturn();

httpHeaders.add("Accept-Language", "fr");
resultGet = this.mockMvc.perform(
get("/error/npe").headers(httpHeaders)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.message").value("Une erreur inconnue s'est produite. Veuillez nous excuser."))
.andReturn();
}

我想处理 url 中的 locale 参数,如 ?lang=en 和 Accept-Language header 作为后备。

作为 REST 应用程序,我正在考虑使用 AcceptHeaderLocaleResolver 类,但它不支持通过 url 参数设置语言环境。

我认为在 REST 应用程序中使用 SessionLocaleResolver 类毫无意义。

这让我留下了 CookieLocaleResolver 类,我并不特别相信它应该在 REST 应用程序中使用。

无论如何,检索到的语言环境仍然是 en 而不是我期望的 fr 。

编辑:

在测试中,使用语句:
httpHeaders.add("Accept-Language", Locale.FRENCH.getLanguage());

不设置语言环境。
但是使用 locale() 确实如此。
此测试通过:
this.mockMvc.perform(
get("/error/npe").headers(httpHeaders).locale(Locale.FRENCH)
.accept(MediaType.APPLICATION_JSON))
.andDo(print()
)
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.message").value(localizeErrorMessage("error.npe", Locale.FRENCH)))
.andReturn();

最佳答案

我找到了解决方案。现在正在使用 Accept-Language header 和 cookie。

public class WebConfiguration extends WebMvcConfigurerAdapter {

@Bean
public LocaleResolver localeResolver() {
return new SmartLocaleResolver();
}

}

public class SmartLocaleResolver extends CookieLocaleResolver {

@Override
public Locale resolveLocale(HttpServletRequest request) {
String acceptLanguage = request.getHeader("Accept-Language");
if (acceptLanguage == null || acceptLanguage.trim().isEmpty()) {
return super.determineDefaultLocale(request);
}
return request.getLocale();
}

}

更新:根据 Thor 的评论,这是一个首先检查 cookie 的解析器,如果没有找到,则检查请求 header :
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = super.determineDefaultLocale(request);
if (null == locale) {
String acceptLanguage = request.getHeader("Accept-Language");
if (acceptLanguage != null && !acceptLanguage.trim().isEmpty()) {
locale = request.getLocale();
}
}
return locale;
}

或者使用更简单的实现(未测试):
private AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver();

@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = super.determineDefaultLocale(request);
if (null == locale) {
locale = acceptHeaderLocaleResolver.resolveLocale(request);
}
return locale;
}

更新:上述解决方案不再有效。

我现在试图在标题中传递接受的语言:
httpHeaders.add(HttpHeaders.ACCEPT_LANGUAGE, "fr_FR");

并在此语言环境解析器中检索它:
@Override
public Locale resolveLocale(HttpServletRequest request) {
for (String httpHeaderName : Collections.list(request.getHeaderNames())) {
logger.debug("===========>> Header name: " + httpHeaderName);
}
String acceptLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
logger.debug("===========>> acceptLanguage: " + acceptLanguage);
Locale locale = super.resolveLocale(request);
logger.debug("===========>> acceptLanguage locale: " + locale.getDisplayCountry());
if (null == locale) {
locale = getDefaultLocale();
logger.debug("===========>> Default locale: " + locale.getDisplayCountry());
}
return locale;
}

但是没有 Accept-Language===========>> Header name 的输出中记录器和 acceptLanguage记录器是空的。

关于Spring REST 处理语言环境更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23738060/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com