【发布时间】:2020-02-09 20:55:57
【问题描述】:
我现在正在寻找多语言网络应用程序的框架。目前在我看来,最好的选择是 Spring MVC。但我面临这样一个事实,即所有开发人员指南都建议以这种方式使用 LocaleChangeInterceptor 切换语言:
http://www.somesite.com/action/?locale=en
很遗憾,我想避免这种情况的原因有很多。如何使语言代码成为 URL 的重要组成部分?例如:
http://www.somesite.com/en/action
谢谢。
UPD:我找到了以下解决方案。它还没有完成,但是可以工作。解决方案由两部分组成 - servlet 过滤器和语言环境解析器 bean。它看起来有点骇人听闻,但我没有看到解决此问题的其他方法。
public class LocaleFilter implements Filter
{
...
private static final String DEFAULT_LOCALE = "en";
private static final String[] AVAILABLE_LOCALES = new String[] {"en", "ru"};
public LocaleFilter() {}
private List<String> getSevletRequestParts(ServletRequest request)
{
String[] splitedParts = ((HttpServletRequest) request).getServletPath().split("/");
List<String> result = new ArrayList<String>();
for (String sp : splitedParts)
{
if (sp.trim().length() > 0)
result.add(sp);
}
return result;
}
private Locale getLocaleFromRequestParts(List<String> parts)
{
if (parts.size() > 0)
{
for (String lang : AVAILABLE_LOCALES)
{
if (lang.equals(parts.get(0)))
{
return new Locale(lang);
}
}
}
return null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
List<String> requestParts = this.getSevletRequestParts(request);
Locale locale = this.getLocaleFromRequestParts(requestParts);
if (locale != null)
{
request.setAttribute(LocaleFilter.class.getName() + ".LOCALE", locale);
StringBuilder sb = new StringBuilder();
for (int i = 1; i < requestParts.size(); i++)
{
sb.append('/');
sb.append((String) requestParts.get(i));
}
RequestDispatcher dispatcher = request.getRequestDispatcher(sb.toString());
dispatcher.forward(request, response);
}
else
{
request.setAttribute(LocaleFilter.class.getName() + ".LOCALE", new Locale(DEFAULT_LOCALE));
chain.doFilter(request, response);
}
}
...
}
public class FilterLocaleResolver implements LocaleResolver
{
private Locale DEFAULT_LOCALE = new Locale("en");
@Override
public Locale resolveLocale(HttpServletRequest request)
{
Locale locale = (Locale) request.getAttribute(LocaleFilter.class.getName() + ".LOCALE");
return (locale != null ? locale : DEFAULT_LOCALE);
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale)
{
request.setAttribute(LocaleFilter.class.getName() + ".LOCALE", locale);
}
}
因此无需在控制器中的每个操作中映射区域设置。下面的例子可以正常工作:
@Controller
@RequestMapping("/test")
public class TestController
{
@RequestMapping("action")
public ModelAndView action(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("test/action");
...
return mav;
}
}
【问题讨论】:
-
嗨@Gris...你完善了这个解决方案吗?
-
也想知道你是否完善了解决方案
-
我不明白你是如何在 setLocale 方法中设置语言环境的,如果我理解正确,你只会在请求中设置一个属性......你能澄清一下吗?
标签: url spring-mvc locale