目录

前言

代码

测试


前言

        在项目中要面临后端返回给前端展示,而展示给别人的告警信息是需要面向不同的语言,比如展示中文还是英文等等。

        这个时候就需要在返回的json中将告警信息根据选择的语言来返回不同的信息。

        

代码

首先新建一个spring boot工程,这里就不多赘述。

在工程中配置自己的国际化文件,XXX.properties,如下图所示,这里的Resource Bundle 'mess'是idea自动生成的,不用管,只需要建立i18n这个资源目录和下面三个properties文件。

spring boot 国际化 springboot国际化 json_AOP

第二步是在spring boot的配置文件中表名是读取哪些文件,如下图,此处是表名读取i18n目录下mess开头的文件。

# 是否开启国际化返回 #lang.open: false spring: messages: basename: i18n.mess

第三步是编写国际化文件读取类,I18nUtils和LocaleMessage类,代码如下,

package com.staryea.i18n;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Locale;

/**
 * @author lw
 * @date 2022/3/15 0015
 * @description
 */
@Component
public class I18nUtils {

    @Autowired
    private LocaleMessage localeMessage;

    /**
     * 获取key
     *
     * @param key
     * @return
     */
    public  String getKey(String key) {
        String name = localeMessage.getMessage(key);
        return name;
    }

    /**
     * 获取指定哪个配置文件下的key
     *
     * @param key
     * @param local
     * @return
     */
    public  String getKey(String key, Locale local) {
        String name = localeMessage.getMessage(key, local);
        return name;
    }
}
package com.staryea.i18n;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import java.util.Locale;

/**
 * @author lw
 * @date 2022/3/15 0015
 * @description
 */
@Component
public class LocaleMessage {
    @Autowired
    private MessageSource messageSource;

    public String getMessage(String code) {
        return this.getMessage(code, new Object[]{});
    }

    public String getMessage(String code, String defaultMessage) {
        return this.getMessage(code, null, defaultMessage);
    }

    public String getMessage(String code, String defaultMessage, Locale locale) {
        return this.getMessage(code, null, defaultMessage, locale);
    }

    public String getMessage(String code, Locale locale) {
        return this.getMessage(code, null, "", locale);
    }

    public String getMessage(String code, Object[] args) {
        return this.getMessage(code, args, "");
    }

    public String getMessage(String code, Object[] args, Locale locale) {
        return this.getMessage(code, args, "", locale);
    }

    public String getMessage(String code, Object[] args, String defaultMessage) {
        return this.getMessage(code, args, defaultMessage, LocaleContextHolder.getLocale());
    }

    public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        return messageSource.getMessage(code, args, defaultMessage, locale);
    }
}

两个工具类写好后,下面就是编写AOP拦截,拦截返回的code,将msg赋值为国际化读取的信息。

此AOP拦截代码如下图所示,

package com.staryea.i18n;

import com.app.frame.util.PageData;
import com.staryea.app.version.VersionController;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author JCccc
 */
@Aspect
@Component
@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "true")
public class LanguageAspect {

    private static final Log LOG = LogFactory.getLog(LanguageAspect.class);

    @Autowired
    I18nUtils i18nUtils;

    @Pointcut("execution(public * com.staryea.app.*.*Controller.*(..))")
    public void annotationLangCut() {
    }

    /**
     * 拦截controller层返回的结果,修改msg字段
     *
     * @param point
     * @param resultObject
     */
    @AfterReturning(pointcut = "annotationLangCut()", returning = "resultObject")
    public void around(JoinPoint point, PageData resultObject) {
        try {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            //从获取RequestAttributes中获取HttpServletRequest的信息
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
            String langFlag = request.getHeader("dimLang");
            if (null != langFlag) {
                String msg = resultObject.getString("result_msg");
                String code = resultObject.getString("result_code");
                if (code!=null&&!"".equals(code)) {
                    code = code.trim();
                    Locale locale = null;
                    if ("zh-CN".equals(langFlag)) {
                        locale = Locale.CHINA;
                    } else if ("en-US".equals(langFlag)) {
                        locale = Locale.US;
                    }

                    if(locale!=null){
                        msg = i18nUtils.getKey(code, locale);
                    }else {
                        msg = i18nUtils.getKey(code);
                    }
                }
                resultObject.put("result_msg",msg);
            }
        } catch (Exception e) {
            LOG.error(e);
        }
    }
}

其中,@ConditionalOnProperty是读取yml中配置的  lang.open的值,为true则AOP生效,否则不生效。

@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "true")

可以在yml中做如下配置,下面是开启国际化,

# 是否开启国际化返回 lang.open: true

测试

在mess_zh_CN.properties和mess.properties中写入如下内容,

0=成功
112=重复操作
113=工号有工牌
114=工牌有工号

在mess_en_US.properties中写入如下内容,

0=success
112=repeat oper
113=code has mac
114=mac has code

 可以看到AOP拦截的是包名为 com.staryea.app下所有包下面的以Controller结尾的,所有的方法。

@Pointcut("execution(public * com.staryea.app.*.*Controller.*(..))")

那么就按照此写一个Controller,如下所示,

spring boot 国际化 springboot国际化 json_AOP_02

 测试类如下,默认返回0.

@GetMapping("/testI18n")
    public PageData testI18n(HttpServletRequest request){
        return RespUtil.getSuccessResp();
    }

然后在postman中调用地址进行测试,

 

spring boot 国际化 springboot国际化 json_java_03

spring boot 国际化 springboot国际化 json_java_04