SpringBoot中对返回结果进行多语言切换方案(本文利用AOP实现)

相信很多朋友在做接口开发的时候返回给客户端的提示需要根据不同的语言切换,如果是客户端的那么客户端自己可以做,如果是服务端返回的,那就只能服务端在返回的同时做处理了,如果一个一个改,我的妈呀,什么时候是个头,唯一正确的方式就是使用AOP来实现,费话不多说,下面先贴上代码:

import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
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.springblade.core.tool.api.R;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
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.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 对请求参数进行拦截修改
 * @author yuxuan
 */
@Aspect
@Component
@AllArgsConstructor
@ConditionalOnProperty(prefix = "lang",name = "open",havingValue = "true")
public class LanguageAspect {

	private String objPreFix = "R";

	@Pointcut("execution(* com.rksj.controller.*.*(..))")
	public void annotationLangCut(){};

	/**
	 * 定义一个并发性Map用来存放信息
	 */
	Map<String, String> tmpMap = new ConcurrentHashMap<>();

	/**
	 * 在构造函数中进行初始化,后面可从配置文件中初始化
	 */
	public LanguageAspect(){
		//初始化 KEY为简体  VALUE为  简体###繁体###英文
		loadSysCfg();

	}

	/**
	 * 从配置文件加载
	 */
	private void loadSysCfg(){
		try{
			//加载配置文件
			Resource resource = new ClassPathResource("language");
			InputStream is = resource.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(is);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String line = "";
			while( (line = bufferedReader.readLine()) != null ){
				//不为空且以#号开头的去掉,注释部分
				if(StringUtils.isNotEmpty(line) && !line.startsWith("#")){
					String[] lines = line.split("###");
					tmpMap.put(lines[0], line);
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}



	/**
	 * 拦截controller层返回的结果,修改msg字段
	 * @param point
	 * @param obj
	 */
	@AfterReturning(pointcut="annotationLangCut()",returning="obj")
	public void around(JoinPoint point, Object obj)  {
		Object backObj = obj;
		try{
			RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
			//从获取RequestAttributes中获取HttpServletRequest的信息
			HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
			String bladeLang = request.getHeader("x-language");
			if(!Objects.isNull(obj) && obj.toString().startsWith(objPreFix)){
				R<?> r = (R) obj;
				String tmpMsg = tmpMap.get(r.getMsg().trim());
				if(StringUtils.isNotEmpty(tmpMsg)){
					String[] tmpMsgs = tmpMsg.split("###");
					//说明格式无问题
					if(tmpMsgs.length == 3){
						if(!Objects.isNull(bladeLang)){
							//简体
							if(bladeLang.equalsIgnoreCase("CN")){
								r.setMsg(tmpMsgs[0]);
								//繁体
							}else if(bladeLang.equalsIgnoreCase("TC")){
								r.setMsg(tmpMsgs[1]);
								//英文
							}else if(bladeLang.equalsIgnoreCase("EN")){
								r.setMsg(tmpMsgs[2]);
							}
							obj = r;
						}
					}
				}
			}
		}catch (Exception e){
			e.printStackTrace();
			//重新赋值给obj,防止try中途修改原始的值
			obj = backObj;
		}
	}
}

配置文件如下:

#格式为 简体中文###繁体中文###英文   行首以#开头的为注释部分
成功###成功###Successful

需要在配置文件中配置

lang.open=true

则可以开启此AOP拦截。R对象为封装的返回对象,其中msg为提示信息。

是不是很简单,感兴趣的小伙伴可以关注我哦,每天更新干货。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章