You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:52:38