Spring MVC / Boot 国际化组件

国际化资源加载

尝试使用application配置

在尝试使用application配置加载文案资源时,会抛出“NoSuchMessageException: No message found under code XXX”的异常,打断点发现自动注入的MessageSource是DelegatingMessageSource,而且没有对资源文件做任何加载,
细节原因参考:https://segmentfault.com/a/1190000010757338

bean配置

放弃application配置后,我想主动对MessageSource进行注入,使用ReloadableResourceBundleMessageSource。

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("classpath:messages/messages");
    messageSource.setCacheSeconds(messagesCache);
    messageSource.setDefaultEncoding("UTF-8");
    return messageSource;
}

basename是文案资源的路径,第一个messages是目录,第二个messages是默认文案和其他语言文案的前缀。

这里写图片描述

在返回结果加入文案

@ControllerAdvice
public class I18nResponseBodyAdvice implements ResponseBodyAdvice<ResultCollect> {
    @Autowired
    private MessageSource messageSource;
    @Autowired
    private AccountService accountService;

    // supports方法判断该返回结果是否要被拦截,如果返回true,则执行beforeBodyWrite方法。
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return ResultCollect.class.isAssignableFrom(methodParameter.getParameterType());
    }

    @Override
    public ResultCollect beforeBodyWrite(ResultCollect resultCollect, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        HttpServletRequest request = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest();
        String local = accountService.getCookie(request, "user-locale");
        Locale locale;
        if (StringUtils.isNotBlank(local)) {
            // locale: zh-CN or en-US
            String[] arr = local.split("-");
            locale = new Locale(arr[0], arr.length > 1 ? arr[1] : "");
        } else {
            locale = Locale.US;
        }
        if (resultCollect != null) {
            resultCollect.setMsg(messageSource.getMessage(resultCollect.getKey(), null, locale));
        }
        return resultCollect;
    }
}

supports方法判断该返回结果是否要被拦截,如果返回true,则执行beforeBodyWrite方法。

beforeBodyWrite方法的参数ServerHttpRequest、ServerHttpResponse,分别传递的是ServletServerHttpRequest、ServletServerHttpResponse,均属于org.springframework.http包下的类型;而在拦截器中常用的HttpServletRequest、HttpServletResponse属于javax.servlet包下的类型。

以zh-CN为例,messageSource.getMessage查找的资源文件顺序为:

  1. messages_zh_CN.properties
  2. messages.properties
  3. messages_zh.properties
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值