Spring cloud Zuul with servlet-api 2.5

时间:2015-12-22 15:17:55

标签: java spring spring-cloud netflix-zuul servlet-2.5

  1. @EnableZuulProxy在servlet 2.5容器下不起作用。是否有任何解决方法可以在servet 2.5容器下获得spring-cloud zuul的工作?

  2. 我也找不到@EnableZuulProxy的注释处理器。请提供推广@EnableZuulProxy的课程,以便我能更好地理解这个注释的真正含义。

2 个答案:

答案 0 :(得分:2)

@EnableZuulProxy来自Spring Cloud,它基于Spring Boot,即Servlet 3.0及更高版本。如果需要使用Servlet 2.5,可以直接使用Netflix API。

@EnableZuulProxy使用@Import(ZuulProxyConfiguration.class)进行元注释,因此我猜这就是当你说" propesses&#34 ;?时的意思如果你不知道@Import是什么,请去阅读Spring。

答案 1 :(得分:2)

Spring Cloud旨在在servlet 3.0上运行。话虽这么说,有可能在servlet 2.5上运行@EnableZuulProxy。我不得不弄清楚这是因为我必须在Tomcat 6中使用它。

主要问题是由于ZuulConfiguration.class,它有以下方法:

@Bean
@ConditionalOnMissingBean(name = "zuulServlet")    
public ServletRegistrationBean zuulServlet() { ... }

这里的问题是ServletRegistrationBean使用javax.servlet.Registration$Dynamic,这在Servlet 3.0之前不可用。这会产生NoClassDefFoundError

要解决此问题,请使用spring-boot-legacy项目首先注册DispatcherServlet。其次,您必须手动创建一个zuul servlet。

<强>的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.dm.gateway.microservicegateway.Application</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>ContextLifecycleFilter</filter-name>
        <filter-class>com.netflix.zuul.context.ContextLifecycleFilter</filter-class>
    </filter>


    <filter-mapping>
        <filter-name>ContextLifecycleFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextAttribute</param-name>
            <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>zuul</servlet-name>
        <servlet-class>com.netflix.zuul.http.ZuulServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

我发现删除自动servlet注册的最佳方法是只生成ZuulConfig ZuulOverrideConfig的逐字副本,然后删除zuulServlet()方法。这是因为ZuulProxyConfiguration扩展了ZuulConfiguration,它似乎创建了bean,即使我试图覆盖它。我不是100%关注这背后的机制,所以可能有更好的方法。

我在ZuulOverrideConfig中做的第二个更改是调用ZuulFilterInitializer的扩展实现,名为&#39; LegacyZuulFilterInitializer`。这是因为出于某种原因,Zuul servlet正在被装箱,并且能够被调用,但没有过滤器被引导。这个扩展是一种让过滤器引导的hacky方式。

接下来,我创建了一个名为ZuulProxyConfiguration的{​​{1}}副本,并将其扩展为ZuulLegacyProxyConfiguraiton

最后,我按如下方式注释了Application类。

ZuulOverrideConfig.class

在所有这些黑客攻击之后,实施终于按预期工作了。我不建议长期使用它,因为它非常黑客。在转移到新版本时,您无法自动获得配置类更新,我无法保证不会随意中断某些内容!

这是使用Spring Cloud 1.1.4.RELEASE

Gist of all the code.