iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >SpringCloud网关(Zuul)如何给多个微服务之间传递共享参数
  • 462
分享到

SpringCloud网关(Zuul)如何给多个微服务之间传递共享参数

2024-04-02 19:04:59 462人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1、使用场景解决方案1解决方案22、代码实现3、成果展现4、总结1、使用场景 因为最近项目需要国际化,但是以前国际化的语言切换是放置在未进行微服务化之前的一个独立的SpringB

1、使用场景

因为最近项目需要国际化,但是以前国际化的语言切换是放置在未进行微服务化之前的一个独立的SpringBoot服务之中。

目前由于业务的需要和不同模块能够复用的要求目前已经拆分为如下服务:zuul网关服务、**dx服务(包含主要服务)、**ai(一些推荐的AI服务)、message(消息咨询服务)、forum(论坛版块服务)等等。

如果还是按照以前的的方式只切换 **dx服务 之中的语言;其他微服务是不知道当前的Request请求是什么语言体系的。

就意味   **dx服务 是en语言,但是其他服务还是 zh(中文语言)。

因为此问题,我本人在项目开始进行国际化改版的时候,我就知道有此问题。 我就知道有此问题。 最开始就是有人不信;最后遇见问题了还是相信了!遇见问题了,总得使用相关的方案来解决此问题。

于是本人就是想到了有如下两种解决方案:

解决方案1

在网关服务(Zuul)之中,写一个统一的切换语言接口;在切换语言的使用同时调用其他服务的切换语言接口。这样实现起来最为简单。

具体如下图所示:

此方法比较原始直接,但是书写代码比较多;想当与每个微服务都得提供一个修改语言体系的接口供 网关(Zuul)

解决方案2

在网关(Zuul)服务层进行语言切换时候获得切换语言的参数;使用 LocaleContextHolder 暂存当前已经切换语言的信息;

然后在Zuul的过滤器之中通过获得当前请求(Request)的参数后,把以前语言切换暂存参数值从LocaleContextHolder获得切换语言的参数值。然后把这个参数传递到其他微服务之中;其他微服务通过Request 即可获得最新切换的语言参数;然后做到顺利获取切换后的最新的语言信息。   

具体如下图所示:   

          

针对方案一与方案二比较后;我选择使用的方案二。

2、代码实现

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        httpservletRequest request = ctx.getRequest();
        String reqUrl=request.getRequestURL().toString();
        HttpSession session = request.getSession();         
    	Map<String, Object> user=(Map<String, Object>) session.getAttribute("user");  
        if(!(reqUrl.contains("permissionUser/userLogin") || (reqUrl.contains("noAuth")) 
        		|| reqUrl.contains("appapi"))) {
        	String[] actProfile = env.getActiveProfiles();
    		String curProfile = actProfile[0];
    		
        	if (StringUtils.startsWith(curProfile, "dev")) { //dev环境不做过滤    			
    			return null;    			
    		} 
        	
    		//判断用户ID是否存在,不存在就跳转到登录界面
        	if (!checkUserIsLogin(ctx, user)) {
        	//	System.out.println("session丢失: " + request.getSession().getId());
        		return null;
        	}
        	
            //放行ignoreUrls中配置的url
        	if(checkIsIgnoreUrl(request)) {
        		addUserToZuulRequestHeader(user);
        		return null;
        	}
        	
        	//检查该url是否有权访问
        	if (!checkIsUrlHasRight(ctx)) {
        		return null;
        	}
        	//从会话之中获得当前登录用户的userId,判断用户是否被踢
        	if (checkUserIsKickout(ctx, user)) {
        		return null;
        	}            
        }
        //可以往后走了,把session放入request的header中
        addUserToZuulRequestHeader(user);  
        //语言包
        setLanguageLocal(request);
        return null;
    }
 
     
	private void setLanguageLocal(HttpServletRequest request) {
		String lang = "zh";
		if (StringUtils.isNotEmpty(request.getParameter("lang"))) {
			lang = request.getParameter("lang");
		}else {
			lang=localeMessageSourceService.getCurrentLanguage();
		}
		switch(lang) {
			case "zh":
				LocaleContextHolder.setLocale(Locale.CHINESE);
				break;
			case "en":
				LocaleContextHolder.setLocale(Locale.ENGLISH);
				break;
			case "fr":
				LocaleContextHolder.setLocale(Locale.FRENCH); 
				break;
		}
		//此处为获得请求的参数 然后在请求的参数里面加入暂存的语言携带参数 lang
		RequestContext ctx = RequestContext.getCurrentContext();
		request.getParameterMap();
		Map<String,List<String>> requestQueryParams=ctx.getRequestQueryParams();
		if(requestQueryParams==null) {
			requestQueryParams=new HashMap<>();
		}
		//String lanGCode=request.getParameter("lang").toString();
		//讲需要新增的参数添加进去,被调用的微服务可以直接获取,就像普通的一样;框架会直接注入进去
		    ArrayList<String> arrayList = new ArrayList<>();
            arrayList.add(lang);       
            requestQueryParams.put("lang", arrayList);
            ctx.setRequestQueryParams(requestQueryParams);
		FrameWorkConstant.MSG_INFO_EMPTY = localeMessageSourceService.getMessage("msg.info.empty");
		FrameWorkConstant.MSG_INFO_SUCCESS = localeMessageSourceService.getMessage("msg.success.operate");
		FrameWorkConstant.MSG_INFO_FAILED= localeMessageSourceService.getMessage("msg.error.unknown");
	}

ChangeLanauageConfigurer

import java.util.Locale; 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.WEB.servlet.config.annotation.InterceptorReGIStry;
import org.springframework.web.servlet.config.annotation.WebmvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
 

@Configuration
public class ChangeLanauageConfigurer extends WebMvcConfigurerAdapter {
 
 
	
	@Bean
    public SessionLocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
//        System.out.println("aaaaaaaaaaaaaaaaaaaaaa");
//        // 设置默认语言
        slr.setDefaultLocale(Locale.CHINESE);       
        return slr;
    }
 
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        // 设置参数名
        lci.setParamName("lang");
        return lci;
    }
 
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}

LocaleMessageSourceService


@Service
public class LocaleMessageSourceService {
	
	@Autowired
	private MessageSource messageSource;
 
    
 
   public String getMessage(String code){
 
      //这里使用比较方便的方法,不依赖request.
      Locale locale = LocaleContextHolder.getLocale();
      String lang = locale.getLanguage();
      if(LanguageConstant.LANGUAGE_FR.equals(lang)) {
    	  locale = new Locale(lang,"FR");
      }
      if(LanguageConstant.LANGUAGE_ZH.equals(lang)) {
    	  locale = new Locale(lang,"CN");
      }
      if(LanguageConstant.LANGUAGE_EN.equals(lang)) {
    	  locale = new Locale(lang,"US");
      }
      
      String message = messageSource.getMessage(code,null,locale);
      return message;
   }
   
   
   public String getCurrentLanguage(){
 
       Locale locale = LocaleContextHolder.getLocale();
       String lang = locale.getLanguage();
       if(StringUtils.isEmpty(lang)) {
       	lang = LanguageConstant.LANGUAGE_EN;
       }
       return lang;
    }  
}

3、成果展现

在网关服务之中切换语言(en)后获得信息

ai服务的语言体系

**dx服务的语言体系

网关切换为中文(zh)后其他服务语言返回

ai服务语言切换结果

**dx服务语言切换结果

4、总结

如果使用简单粗暴的方法,直接通过网关调用其他微服务;虽然能够实现功能;但是此方法比较笨重;同时书写的代码比较多。为后期维护带来很大的不便利。

如果使用方案二在网关层进行统一处理,借助语言切换的能够在网关(Zuul)服务进行暂存和传递;同时动态添加切换语言后的参数到Request之中;能够便捷的把语言参数带到其他微服务之中。此方法值得推崇。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: SpringCloud网关(Zuul)如何给多个微服务之间传递共享参数

本文链接: https://www.lsjlt.com/news/143407.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作