springrest处理区域设置更改
我试图在Spring3REST应用程序中处理区域设置更改 但区域设置没有更改为fr 控制台日志显示: 2014-05-19 14:29:46214调试[AbstractExceptionHandler]语言环境:en 以下是我的配置:springrest处理区域设置更改,spring,rest,locale,Spring,Rest,Locale,我试图在Spring3REST应用程序中处理区域设置更改 但区域设置没有更改为fr 控制台日志显示: 2014-05-19 14:29:46214调试[AbstractExceptionHandler]语言环境:en 以下是我的配置: @Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableRes
@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;
}
}
我希望将url中的locale参数作为?lang=en处理,并将Accept Language头作为回退处理
作为一个REST应用程序,我考虑使用AcceptHeaderLocalerResolver类,但它不支持通过url参数设置语言环境
我认为在REST应用程序中使用SessionLocalerResolver类没有什么意义
这就剩下了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标头和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,如果没有找到,则检查请求头:
@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;
}
或者使用更简单的实现(未经测试):
更新:上述解决方案不再有效
我现在尝试在标题中传递接受的语言:
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;
}
但是在=============>>头名称
记录器的输出中没有接受语言
,并且接受语言
记录器是空的。当我们使用
@Bean
public SessionLocaleResolver localeResolver(){
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
它能够从查询参数中接受区域设置
{{url}}/com-manh-cp-ext-order/api/ext/ex23order/greeting?language=es
我已将区域设置解析器配置为处理lang=fr,但正在使用Accept Language标头传递区域设置。难怪没有解析区域设置。但是如果使用Accept Language标头发送,它仍然看不到区域设置。我尝试了CookieloCalerResolver类和SessionLocalerResolver类,但没有效果。如果SEO更让你担心,在路径中传递语言可以让爬虫用所有支持的语言索引你的站点。让我们关注一下这个问题——Spring核心团队正在考虑这一公关,以支持这一点——太好了!我将使用这一点。也许切换解析器,所以cookie首先检查,如果没有cookie,然后使用接受语言。HEI THOR,TKK为DIN输入,库尔在SE EN诺德曼IDAG:-)Selv Er Jeg Frksman Frn普罗旺斯OG JEG KAN-SNAKKE照亮NursSK Furdi-Jeg Har JoBet et a PAR r HOS BBS(NETE)I NurGE,DeVaValMSOMT!阿克库拉特·恩杰格·奥普德拉特·西德·弗兰克丽克·奥格·维哈尔和里克提格·诺尔斯克·维德·艾德·德特·格瑞特、贝根·斯多姆·索姆·贝根:我是斯蒂芬·赫迪格·克杰克特·希尔森的旅店。阿尔沃尔·德雷·奥古斯·贾恩哈尔·韦尔赫斯滕·贝金特。我在奥克托伯的土地上生活。Jeg ble glad når du Oppdatert ditt svar,Jeg skal ta det i bruk nåi en app for vitenskapelig publisering(npi.nsd.no)der vi skal ha to språk。请注意,CookieLocaleResolver是一种实现,在自定义设置的情况下使用发送回用户的cookie,返回到指定的默认区域设置或请求的accept标头区域设置。-可能会使SmartLocaleResolver变得多余。
@Bean
public SessionLocaleResolver localeResolver(){
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
{{url}}/com-manh-cp-ext-order/api/ext/ex23order/greeting?language=es