如何在 Zuul 过滤器中发送 RestTemplate/Request?

Posted

技术标签:

【中文标题】如何在 Zuul 过滤器中发送 RestTemplate/Request?【英文标题】:How to send a RestTemplate/Request inside a Zuul Filter? 【发布时间】:2020-04-12 14:35:54 【问题描述】:

我有一个核心 MS,它只是一个传递,并向所有传入请求添加标头。我试图在 Zuul 过滤器中调用 Validate Session API,以便在添加所有请求的标头之前先调用它,如果出现此错误,事务将不会继续。但是,似乎我无法在过滤器内发送基本的休息模板请求。那我做错了什么还是我错过了什么?这是代码sn-p。

public class WebFilter extends ZuulFilter 

 @Override
    public String filterType() 

        RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
        restTemplate.getForEntity(this.loginService.validateCache(hostUrl,validateSessionUrl, ctx.getRequest().getParameter("SessionId")).toUriString(),String.class

         ctx.addZuulRequestHeader("clientid", clientId);
        ctx.addZuulRequestHeader("clientsecret", clientSecret);
        return "pre";
    

其余模板部分给出了ff。错误。但是,删除它将使应用程序正常工作,但是我需要该休息模板来调用验证 API。我应该把它放在别的地方,还是别的什么地方?

2019-12-20 10:11:50.337 错误 4224 --- [主要] os.s.boot.SpringApplication : 应用启动失败

org.springframework.context.ApplicationContextException:无法 启动嵌入式容器;嵌套异常是 org.springframework.boot.context.embedded.EmbeddedServletContainerException: 无法在以下位置启动嵌入式 Tomcat org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:535) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:313) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 com.bdo.fintech.web.core.Application.main(Application.java:26) ~[classes/:na] 原因: org.springframework.boot.context.embedded.EmbeddedServletContainerException: 无法在以下位置启动嵌入式 Tomcat org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:116) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.(TomcatEmbeddedServletContainer.java:83) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:530) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:176) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] ... 8个常用框架 省略原因: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建具有名称的 bean 时出错 'org.springframework.cloud.netflix.zuul.ZuulConfiguration$ZuulFilterConfiguration': 通过字段“过滤器”表示的不满足的依赖关系:错误 创建名称为 'webFilter' 的 bean com.bdo.fintech.web.core.Application:通过工厂进行 Bean 实例化 方法失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.bdo.fintech.web.core.WebFilter]:工厂方法 'webFilter' 抛出异常;嵌套异常是 java.lang.NullPointerException;嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名称为 'webFilter' 的 bean com.bdo.fintech.web.core.Application:通过工厂进行 Bean 实例化 方法失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.bdo.fintech.web.core.WebFilter]:工厂方法 'webFilter' 抛出异常;嵌套异常是 java.lang.NullPointerException 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:233) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:181) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:162) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.web.servlet.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:79) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:241) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:228) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:89) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:213) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 在 org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 在 org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 在 org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 在 java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] 在 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] 在 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] 在 java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 引起:org.springframework.beans.factory.BeanCreationException: 创建名称为“webFilter”的 bean 时在 com.bdo.fintech.web.core.Application:通过工厂进行 Bean 实例化 方法失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.bdo.fintech.web.core.WebFilter]:工厂方法 'webFilter' 抛出异常;嵌套异常是 java.lang.NullPointerException 在 org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1145) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1049) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 35个常用框架 省略原因: org.springframework.beans.BeanInstantiationException:失败 实例化 [com.bdo.fintech.web.core.WebFilter]:工厂方法 'webFilter' 抛出异常;嵌套异常是 java.lang.NullPointerException 在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 49个常用框架 省略引起:java.lang.NullPointerException: null at com.bdo.fintech.web.core.WebFilter.filterType(WebFilter.java:89) 〜[类/:na]在 com.netflix.zuul.ZuulFilter.disablePropertyName(ZuulFilter.java:89) ~[zuul-core-1.1.0.jar:1.1.0] 在 com.netflix.zuul.ZuulFilter.(ZuulFilter.java:54) ~[zuul-core-1.1.0.jar:1.1.0] 在 com.bdo.fintech.web.core.WebFilter.(WebFilter.java:34) 〜[类/:na]在 com.bdo.fintech.web.core.Application.webFilter(Application.java:31) 〜[类/:na]在 com.bdo.fintech.web.core.Application$$EnhancerBySpringCGLIB$$c625e823.CGLIB$webFilter$0() 〜[类/:na]在 com.bdo.fintech.web.core.Application$$EnhancerBySpringCGLIB$$c625e823$$FastClassBySpringCGLIB$$c2090f8d.invoke() 〜[类/:na]在 org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 com.bdo.fintech.web.core.Application$$EnhancerBySpringCGLIB$$c625e823.webFilter() 〜[类/:na]在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 方法)~[na:na] 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] 在 java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] 在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 50个常用框架 省略

进程以退出代码 1 结束

【问题讨论】:

你能粘贴整个 WebFilter.java 文件吗?我更关心你在 WebFilter.java line#89 处所做的事情 【参考方案1】:

为您的过滤器逻辑覆盖 run() 方法

    @Override
    public Object run() 
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

...

        return null;
    

https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html#zuul-developer-guide-sample-pre-filter

【讨论】:

【参考方案2】:

我可以通过将 RestTemplate 移动到一个确定请求是否为空的条件中来解决此问题

if(ctx.getRequest() != null) 
 // Put Rest template code here
 else 
// Some more code that will handle when the request is null

【讨论】:

以上是关于如何在 Zuul 过滤器中发送 RestTemplate/Request?的主要内容,如果未能解决你的问题,请参考以下文章

zuul入门过滤器

zuul过滤器

SpringCloud入门: Zuul 过滤器详解

如何在 Zuul 后置过滤器中获取响应正文?

如何在 Zuul 后置过滤器中拦截和编辑响应正文?

基于 Spring Cloud 微服务与 Zuul 的 Spring CORS 过滤器问题