Struts 6.3.0.1+JDK17下如何强制显示英文数字不受locale影响?
解决Struts 6.3.0.1中数字显示不受Locale影响的问题
问题背景
在Struts 6.3.0.1 + JDK8环境下,以下代码输出1, 2, 3,:
<s:iterator begin="1" end="3"> <s:property value="top"/>, </s:iterator>
切换到JDK17并配置struts.locale=fa_IR后,输出变为波斯语数字۱, ۲, ۳,。网站依赖英文数字运行,曾尝试通过session.setAttribute(Config.FMT_LOCALE, new Locale("en", "US"));解决但未生效。
可行解决方案
方案1:强制指定数字格式化的Locale
使用Struts的getText方法结合数字格式化模式,显式指定英文Locale:
<s:iterator begin="1" end="3"> <s:property value="%{getText('{0,number,#}', {top}, new java.util.Locale('en', 'US'))}" />, </s:iterator>
或者使用<s:formatNumber>标签直接指定Locale:
<s:iterator begin="1" end="3"> <s:formatNumber value="%{top}" locale="en_US" pattern="#"/>, </s:iterator>
方案2:直接将数字转为字符串输出
跳过Struts的Locale格式化逻辑,将数字直接转为字符串:
<s:iterator begin="1" end="3"> <s:property value="%{String.valueOf(top)}" />, </s:iterator>
此方法简单直接,适合不需要复杂数字格式化的场景。
方案3:全局配置数字格式化Locale
如果需要全局统一强制使用英文数字格式化,可以自定义NumberFormatProvider,在应用启动时注册:
import java.text.NumberFormat; import java.text.spi.NumberFormatProvider; import java.util.Locale; public class EnglishNumberFormatProvider extends NumberFormatProvider { @Override public NumberFormat getInstance(Locale locale) { return NumberFormat.getInstance(Locale.US); } @Override public NumberFormat getIntegerInstance(Locale locale) { return NumberFormat.getIntegerInstance(Locale.US); } // 按需实现其他NumberFormat方法(如getCurrencyInstance等) }
然后在src/main/resources/META-INF/services/java.text.spi.NumberFormatProvider文件中添加:
com.yourpackage.EnglishNumberFormatProvider
此方法会覆盖所有Locale下的数字格式化行为,适合全局需要统一英文数字的场景。
方案4:临时切换请求Locale
通过自定义拦截器,在请求处理时临时将Struts的Locale切换为en_US,处理完后恢复原Locale:
public class ForceEnglishNumberLocaleInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { ActionContext context = invocation.getInvocationContext(); Locale originalLocale = context.getLocale(); try { context.setLocale(Locale.US); return invocation.invoke(); } finally { context.setLocale(originalLocale); } } }
然后在struts.xml中注册并添加到拦截器栈:
<interceptors> <interceptor name="forceEnglishNumber" class="com.yourpackage.ForceEnglishNumberLocaleInterceptor"/> <interceptor-stack name="defaultStack"> <interceptor-ref name="forceEnglishNumber"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors>
注意此方法会影响所有依赖Locale的标签行为,需根据业务场景评估是否适用。
内容的提问来源于stack exchange,提问作者Alireza Fattahi
相关产品推荐
相关产品推荐

