struts2本地化通过在操作名称中嵌入语言环境代码而不是使用...?request_locale = <locale_code> </locale_code>

时间:2011-01-19 06:55:32

标签: localization internationalization struts2

大家好,

我想在用struts 2编写的网站中进行本地化功能。据我所知,这样做的标准方法是使用以下方式获取: http://.../namespace/action_name?request_locale =&lt; locale code&gt;

但是,我的老板不喜欢这种毛茸茸的网址。相反,我需要以下列方式编写它:

http://.../namespace/a_param/<locale代码&gt; / another_param ...

我试图将struts.xml中的动作映射更改为

&lt; action name =“* / * ...”...&gt;      &lt; param name =“locale”&gt; {2}&lt; / param&gt;      ... &LT; /作用&gt;

它不起作用

之后我将其改为

&lt; action name =“* / * ...”...&gt;      &lt; param name =“request_locale”&gt; {2}&lt; / param&gt;      ... &LT; /作用&gt;

它不起作用T_T

顺便说一句,我知道有把ActionContext.getContext()。setLocale(new Locale(...));在行动中,基本上改变了该实例的语言环境。然而,似乎效果只是暂时的(相反,i18n会在会话中保存所选的语言环境,这基本上使它非常持久。

那么,如何通过在网址中嵌入区域设置代码来更改区域设置?

非常感谢您的帮助= D

3 个答案:

答案 0 :(得分:1)

我对本地人做的不多,但是i18n应该通过标题从浏览器自动确定正确的本地,不需要在网址中添加任何内容。只要有特定语言环境的语言包,它就会尝试从该文件中提取属性。

此页面显示了使用基本i18n的示例(仅查看了一下,我个人总是从http://struts.apache.org/2.x/开始,但教程/指南有点干。

为什么你需要在网址中引用任何关于语言的内容?就个人而言,如果用户确实要覆盖默认语言环境,我会提供某种形式的控件(菜单)来执行此操作。然后我会在session中设置一个变量然后我会创建一个拦截器,它会在会话上使用local参数调用setLocale(如果有一个值集)。这样就不需要将参数嵌入到单个页面中,并且本地不在URL中。

有一种方法可以使用url做你想要的东西......我认为,在允许使用斜杠的操作名称中,可以使用约定和斜线。如果我记得,我会回复。但我认为上述通常是一种更好的方法。

编辑:考虑到您要完成的任务,我可以看到两种截然不同的解决方案。

1)您可以使用代理,传入的网址www.example.com/en/和www.example.com/fr/可以映射到不同的网络应用程序甚至是同一个网络应用程序,但网址是写入适合您的应用程序的表单。可以做到这一点的工具包括:iptables,apache mod_rewrite,squid ......以及众多其他工具。如果在一台服务器上处理多个ip addressses / urls / applications,这种解决方案会更有价值。

2)你可以设置struts2属性 struts.enable.SlashesInActionNames 然后使用通配符你可以做类似的事情:

<action name="*/*">
  <result>/WEB-INF/content/{1}/{2}.jsp</result>
<action>

您还可以将参数传递给操作,每个星号在操作名称中找到{1},{2}等。听起来您可能需要此功能。如果其他人知道它现在让我逃脱了如何使用struts2-conventions-plugin捕获这些url的部分内容,那么动作可以利用它们我会发现它很有趣。

答案 1 :(得分:0)

@Quaternion

基本上意图是,该网站有几个国家“子网站”。根据用户的IP地址,他/她将被重定向到国家“子网站”。就像当您打开www.google.com时,您可能会被重定向到www.google.com.country_domain。

每个国家“子网站”都有多种语言,有1种默认语言。就像你打开谷歌以色列网站一样,默认情况下你会看到一个用希伯来语写的网站,虽然你可以通过选择英文来覆盖这个默认选择。

在我计划的网站上,按照isreal网站和希伯来语的例子,它应该是这样的:

  1. 用户在以色列
  2. 他正在开放www.abcdef.com
  3. 服务器正在认识到客户端在以色列。以色列“子网站”可以选择3种语言:希伯来语,阿拉伯语,英语。默认的是希伯来语,但客户可以覆盖此选择
  4. 然后用户被重定向到www.abcdef.com/il/he(“il”代表以色列国家,“he”代表希伯来语)
  5. 但是用户显然是英国游客,不了解希伯来语或阿拉伯语。所以他/她选择了英语
  6. 他/她将被重定向到www.abcdef.com/il/en("en“代表英语)
  7. 下次客户再次在以色列打开www.abcdef.com时(假设饼干和会议仍然存在),他/她将被重定向到www.abcdef.com/il/en
  8. 你的帮助= D

答案 2 :(得分:0)

我绝对有责任将区域设置处理为interceptor

以下是Create an Interceptor的教程。

此拦截器可以放在由所有(或大多数)传入请求共享的公共堆栈中,它将分配区域设置

ActionContext.getContext().setLocale(locale);

有适当的逻辑可以考虑:

  • 查询字符串参数
  • 存储的用户首选项
  • 饼干
  • 会话
  • 浏览器偏好设置(在请求中)