Tôi hiện đang tìm kiếm một khuôn khổ cho các ứng dụng web đa ngôn ngữ. Tại thời điểm này có vẻ như với tôi rằng sự lựa chọn tốt nhất là Spring MVC. Nhưng tôi phải đối mặt với thực tế là tất cả các hướng dẫn cho các nhà phát triển cho thấy để chuyển đổi ngôn ngữ sử dụng LocaleChangeInterceptor theo cách như vậy:Địa điểm là một phần của URL trong Spring MVC
http://www.somesite.com/action/?locale=en
Thật không may, có một số lý do tại sao tôi muốn tránh điều này. Làm thế nào tôi có thể làm cho mã ngôn ngữ trở thành một phần thiết yếu của URL? Ví dụ:
http://www.somesite.com/en/action
Cảm ơn.
UPD: Tôi đã tìm thấy giải pháp sau. Nó chưa hoàn chỉnh, nhưng hoạt động. Giải pháp bao gồm hai phần - bộ lọc servlet và bean resolver locale. Nó trông hơi chút hackish, nhưng tôi không thấy cách nào khác để giải quyết vấn đề này.
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);
}
}
Vì vậy, không cần phải ánh xạ miền địa phương trong mỗi hành động trong bộ điều khiển. Ví dụ sau đây sẽ hoạt động tốt:
@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 ... Bạn đã đánh bóng giải pháp này? – user683887
Ngoài ra tự hỏi nếu bạn đã đánh bóng giải pháp –
Tôi không hiểu cách bạn đặt ngôn ngữ trong phương thức setLocale, bạn chỉ đặt thuộc tính trong yêu cầu nếu tôi đã hiểu đúng ... Bạn có thể làm rõ? – 0m4r