spring国际化访问数据空指针问题记录

发布时间 2023-03-22 21:16:51作者: 三号小玩家
@Controller



@RequestMapping("/ops/hbase/cluster")

public class HBaseClusterManageController {

private List<String> inComputerRooms = Arrays.asList(/*replaced by i18n tool*/

ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.inComputerRooms.yìn_ní", null, "印尼", LocaleContextHolder.getLocale()),  

ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.inComputerRooms.mĕi_guó", null, "美国", LocaleContextHolder.getLocale()));



private List<String> hkComputerRooms = Arrays.asList( 

 ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.hkComputerRooms.xiāng_găng", null, "香港", LocaleContextHolder.getLocale()));
}
springmvc的不分离项目前端vm,做的国际化,通过en和zh启动后,这个list调用之后会出现异常,如果正常的使用Arrays.asList("香港"),就不报错。

报错信息为:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxx.ops.web.controller.ops.hbase_v2.HBaseClusterManageController' defined in file [xxx]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [xxx.ops.hbase_v2.HBaseClusterManageController]: Constructor threw exception; nested exception is java.lang.NullPointerException



因为这个会进行配置文件的交互,会走messages_en.properties啥的,我就在本地的private List<String> inComputerRooms 上刚刚加了@Autowired,发现结果还是这样。


初步解决方案:

发现这个list在类的公共区域会报错,把list初始化信息放入正在使用的方法中,没有问题,缺点代码冗余。
多个方法都存在一份副本。

专业人士推荐方案:

这个异常可能是由于在初始化 HBaseClusterManageController 控制器时,尝试访问 ApplicationContextHolder 上下文之前,LocaleContextHolder 上下文尚未设置 Locale 导致的。
因为在创建 HBaseClusterManageController 实例时,会立即执行其构造函数,而在构造函数中引用了 LocaleContextHolder.getLocale(),如果此时 LocaleContextHolder 上下文尚未设置 Locale,则可能会返回 null。
可以尝试将这些 List 的初始化代码移动到 @PostConstruct 方法中,这样可以确保 Locale 在初始化 List 之前正确设置
 List<String> hkComputerRooms =null;
    List<String> inComputerRooms =null;

    @PostConstruct
    private void init() {
        inComputerRooms = Arrays.asList(
                ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.inComputerRooms.yìn_ní", null, "印尼", LocaleContextHolder.getLocale()),
                ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.inComputerRooms.mĕi_guó", null, "美国", LocaleContextHolder.getLocale())
        );
        hkComputerRooms = Arrays.asList(
                ApplicationContextHolder.getApplicationContext().getMessage("java.HBaseClusterManageController.hkComputerRooms.xiāng_găng", null, "香港", LocaleContextHolder.getLocale())
        );

    }

试了不好使。