Sto cercando un framework per applicazioni Web multilingue. Al momento mi sembra che la scelta migliore sia Spring MVC. Ma ho dovuto affrontare il fatto che tutte le linee guida per gli sviluppatori suggeriscono di cambiare lingue utilizzando LocaleChangeInterceptor in tal modo:Locale come parte dell'URL in Spring MVC
http://www.somesite.com/action/?locale=en
Purtroppo, ci sono una serie di motivi per cui vorrei evitare questo. Come posso rendere il codice della lingua una parte essenziale dell'URL? Per esempio:
http://www.somesite.com/en/action
Grazie.
UPD: Ho trovato la seguente soluzione. Non è ancora completo, ma funziona. La soluzione consiste in due parti: filtro servlet e bean resolver locale. Sembra un po 'hacker, ma non vedo altro modo per risolvere questo problema.
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);
}
}
Quindi non è necessario mappare le impostazioni locali in ciascuna azione nei controller. Il seguente esempio funziona bene:
@Controller
@RequestMapping("/test")
public class TestController
{
@RequestMapping("action")
public ModelAndView action(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("test/action");
...
return mav;
}
}
Hi @Gris ... Hai lucidato questa soluzione? – user683887
Mi chiedo anche se hai lucidato la soluzione –
Non capisco come si imposta la locale nel metodo setLocale, si imposta un attributo nella richiesta solo se ho capito bene ... Potresti chiarire? – 0m4r