Struts2 6.1.2.1中LocalizedTextUtil替代方案及空指针问题求助
问题解决步骤
问题根源
你直接通过new StrutsLocalizedTextProvider()创建的实例没有被Struts容器管理,而DefaultTextProvider依赖的是由Struts容器注入的LocalizedTextProvider实例,因此会出现空指针异常。正确的做法是通过自定义TextProviderFactory来统一管理资源包和实例创建。
1. 实现自定义StrutsTextProviderFactory
继承Struts默认的工厂类,在创建LocalizedTextProvider实例时统一添加所有模块的资源包:
import com.opensymphony.xwork2.LocalizedTextProvider; import org.apache.struts2.StrutsTextProviderFactory; import org.apache.struts2.provider.StrutsLocalizedTextProvider; public class CustomStrutsTextProviderFactory extends StrutsTextProviderFactory { @Override public LocalizedTextProvider createInstance() { StrutsLocalizedTextProvider provider = (StrutsLocalizedTextProvider) super.createInstance(); // 添加所有模块的消息资源文件 provider.addDefaultResourceBundle("XYZMessageResources"); provider.addDefaultResourceBundle("OtherModuleMessageResources"); // 其他模块资源 return provider; } }
2. 配置Struts使用自定义工厂
有两种配置方式二选一:
方式一:通过struts.properties配置
在项目的src/main/resources下的struts.properties中添加:
struts.xworkTextProviderFactory=com.yourpackage.CustomStrutsTextProviderFactory
方式二:通过struts.xml配置
在struts.xml中添加常量配置:
<struts> <constant name="struts.xworkTextProviderFactory" value="com.yourpackage.CustomStrutsTextProviderFactory" /> </struts>
3. 清理旧代码
删除各模块初始化类中的静态初始化代码,因为资源包的注册已经由自定义工厂统一处理,无需再手动创建StrutsLocalizedTextProvider实例。
4. 调整自定义TextProviderSupport的依赖注入
确保自定义TextProviderSupport通过Struts容器注入DefaultTextProvider,而非手动实例化:
import com.opensymphony.xwork2.TextProvider; import com.opensymphony.xwork2.DefaultTextProvider; public class CustomTextProviderSupport implements TextProvider { private final DefaultTextProvider defaultTextProvider; // 构造注入,Struts容器会自动传入实例 public CustomTextProviderSupport(DefaultTextProvider defaultTextProvider) { this.defaultTextProvider = defaultTextProvider; } @Override public String getText(String key) { String originalText = defaultTextProvider.getText(key); // 实现ANSI转UTF8的逻辑 return convertAnsiToUtf8(originalText); } // 重写其他TextProvider接口方法... private String convertAnsiToUtf8(String text) { // 你的转换逻辑 return text; } }
5. 调整拦截器与Action的配置
- 自定义
I18nInterceptor中,不要手动实例化CustomTextProviderSupport,而是通过Struts容器注入:
<struts> <package name="default" extends="struts-default"> <interceptors> <interceptor name="customI18n" class="com.yourpackage.CustomI18nInterceptor"> <param name="textProvider">com.yourpackage.CustomTextProviderSupport</param> </interceptor> <interceptor-stack name="customStack"> <interceptor-ref name="customI18n"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="customStack"/> </package> </struts>
- 自定义
ActionSupport中,通过容器注入TextProvider而非手动创建:
public class CustomActionSupport extends ActionSupport { private TextProvider textProvider; public void setTextProvider(TextProvider textProvider) { this.textProvider = textProvider; } public String execute() { String message = textProvider.getText("some.key"); // 业务逻辑 return SUCCESS; } }
内容的提问来源于stack exchange,提问作者soumitra goswami
相关产品推荐
相关产品推荐

