Spring MVC 4.3如何限制Locale仅允许指定语言并抛出异常?
解决Spring MVC 4.3限制允许的Locale并拦截非法值问题
要实现仅允许指定Locale(如en、hi),并对非法值抛出IllegalArgumentException,可以通过自定义LocaleResolver或自定义LocaleChangeInterceptor来实现,以下是具体方案:
方案一:自定义CookieLocaleResolver(推荐,覆盖所有Locale来源)
继承Spring自带的CookieLocaleResolver,重写resolveLocale方法,添加Locale合法性校验逻辑,确保只有允许的Locale能被处理,非法值直接抛异常。
自定义Resolver代码
import org.springframework.web.servlet.i18n.CookieLocaleResolver; import javax.servlet.http.HttpServletRequest; import java.util.Locale; import java.util.Set; public class RestrictedCookieLocaleResolver extends CookieLocaleResolver { // 定义允许的Locale集合,可根据需求扩展 private static final Set<Locale> ALLOWED_LOCALES = Set.of( Locale.ENGLISH, new Locale("hi") ); @Override public Locale resolveLocale(HttpServletRequest request) { // 先执行父类逻辑获取请求中的Locale(支持URL参数、Cookie、请求头等来源) Locale requestedLocale = super.resolveLocale(request); // 校验Locale是否在允许列表中 if (!ALLOWED_LOCALES.contains(requestedLocale)) { throw new IllegalArgumentException("不支持的Locale: " + requestedLocale); } return requestedLocale; } }
Spring配置替换默认Resolver
XML配置方式
<!-- 注册自定义LocaleResolver --> <bean id="localeResolver" class="com.yourpackage.RestrictedCookieLocaleResolver"> <property name="cookieName" value="localeCookie"/> <!-- 设置默认Locale,当无合法Locale时使用 --> <property name="defaultLocale" value="en"/> <!-- 其他原有Cookie配置,比如过期时间等 --> <property name="cookieMaxAge" value="31536000"/> </bean> <!-- 保留Locale切换拦截器,处理URL参数 --> <mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="locale"/> </bean> </mvc:interceptors>
Java配置方式
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Bean public LocaleResolver localeResolver() { RestrictedCookieLocaleResolver resolver = new RestrictedCookieLocaleResolver(); resolver.setCookieName("localeCookie"); resolver.setDefaultLocale(Locale.ENGLISH); resolver.setCookieMaxAge(31536000); return resolver; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor(); interceptor.setParamName("locale"); return interceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeChangeInterceptor()); } }
方案二:自定义LocaleChangeInterceptor(仅校验URL参数)
如果只需要拦截URL参数中的非法Locale值,可以自定义LocaleChangeInterceptor,在请求进入Resolver之前提前校验参数。
自定义拦截器代码
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Set; public class RestrictedLocaleChangeInterceptor extends LocaleChangeInterceptor { // 定义允许的Locale字符串集合 private static final Set<String> ALLOWED_LOCALE_CODES = Set.of("en", "hi"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String localeParam = request.getParameter(getParamName()); // 当参数存在且不在允许列表中时抛异常 if (localeParam != null && !ALLOWED_LOCALE_CODES.contains(localeParam)) { throw new IllegalArgumentException("不支持的Locale参数: " + localeParam); } return super.preHandle(request, response, handler); } }
配置替换拦截器
在XML或Java配置中,将原来的LocaleChangeInterceptor替换为自定义的即可。
说明
- 方案一覆盖所有Locale来源(URL参数、Cookie、
Accept-Language请求头),适合全面限制Locale的场景; - 方案二仅校验URL参数中的Locale值,适合只需要限制通过URL切换Locale的场景;
- 允许的Locale集合可根据业务需求扩展,比如支持
en_US、hi_IN等具体地区Locale,只需在集合中添加对应Locale实例或字符串即可。
内容的提问来源于stack exchange,提问作者Chetan Ahirrao
相关产品推荐
相关产品推荐

