[英]Spring LocalResolver based on query parameter 'lang=en'?
Can I tell spring-boot
to automatically resolve the requested locale
by a queryparameter, eg &lang=en
?我可以告诉
spring-boot
通过查询参数自动解析请求的locale
,例如&lang=en
吗?
I would like to give the query param precedence over Accept-Language
parameter.我想让查询参数优先于
Accept-Language
参数。
I found the following two properties, but nothing about a query param.我发现了以下两个属性,但与查询参数无关。
spring.mvc.locale= # Locale to use. By default, this locale is overridden by the "Accept-Language" header.
spring.mvc.locale-resolver=accept-header # Define how the locale should be resolved.
I tried as follows, which gives an exception:我尝试如下,这给出了一个例外:
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
Results in:结果是:
java.lang.UnsupportedOperationException: Cannot change HTTP accept header - use a different locale resolution strategy
The solution is probably as follows.解决办法大概如下。 Still I find the setup very counterintuitive.
我仍然发现设置非常违反直觉。 Especially I would have expected that:
特别是我会期望:
LocaleChangeInterceptor
registers itself, but does not and have to call addInterceptors()
explicit LocaleChangeInterceptor
注册自己,但没有并且必须显式调用addInterceptors()
spring.mvc.locale
parameter is still set into the custom LocaleResolver, but does not and have to override manually from WebMvcProperties
spring.mvc.locale
参数仍设置为自定义 LocaleResolver,但不会并且必须从WebMvcProperties
手动覆盖If all of this is desired, the docs might probably need more explanation on this.如果需要所有这些,文档可能需要对此进行更多解释。
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
@Bean
public AcceptHeaderLocaleResolver localeResolver(WebMvcProperties mvcProperties) {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver() {
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
LocaleContextHolder.setLocale(locale);
}
};
localeResolver.setDefaultLocale(mvcProperties.getLocale());
return localeResolver;
}
}
Update improved version after discussion:讨论后更新改进版本:
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Bean
public AcceptHeaderLocaleResolver localeResolver(WebMvcProperties mvcProperties) {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver() {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String locale = request.getParameter("lang");
return locale != null
? org.springframework.util.StringUtils.parseLocaleString(locale)
: super.resolveLocale(request);
}
};
localeResolver.setDefaultLocale(mvcProperties.getLocale());
return localeResolver;
}
}
First, let's see what happen:首先,让我们看看会发生什么:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.UnsupportedOperationException: Cannot change HTTP accept header - use a different locale resolution strategy
...
Caused by: java.lang.UnsupportedOperationException: Cannot change HTTP accept header - use a different locale resolution strategy
at org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver.setLocale(AcceptHeaderLocaleResolver.java:142) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.i18n.LocaleChangeInterceptor.preHandle(LocaleChangeInterceptor.java:154) ~[spring-webmvc-5.3.2.jar:5.3.2]
...
After debug, you will know:调试后,你会知道:
accept-header
not support preHandle
, you cannot use LocaleChangeInterceptor
accept-header
不支持preHandle
,你不能使用LocaleChangeInterceptor
accept-header
have not any supported languages, you must add them manual. accept-header
没有任何支持的语言,您必须手动添加它们。 You can see this issue . accept-header
only work when you set supported languages and the language match Content-Language
from client browser. accept-header
仅在您设置支持的语言并且语言匹配来自客户端浏览器的Content-Language
时才有效。
So, you needn't use spring.mvc.locale-resolver
or spring.web.locale-resolver
.所以,你不需要使用
spring.mvc.locale-resolver
或spring.web.locale-resolver
。 Now spring 5.3.2 , no properties you need.现在spring 5.3.2 ,您不需要任何属性。
The way for your example to solve this is appending another LocaleResolver
: spring.io为您的例子来解决这个问题的方法是追加其他
LocaleResolver
: spring.io
@Bean
public LocaleResolver localeResolver() {
return new SessionLocaleResolver();//new CookieLocaleResolver();
}
And set:并设置:
spring:
main:
allow-bean-definition-overriding: true # SpringBoot>=2.1.0
web:
locale: en # default
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.