Java 如何将web.xml servlet init param外部化?Spring DelegatingFilterProxy用于servlet?

Java 如何将web.xml servlet init param外部化?Spring DelegatingFilterProxy用于servlet?,java,spring,servlets,Java,Spring,Servlets,我有一个无法修改的第三方servlet。它接受我想要外部化的init参数(来自web.xml) 我可以使用外部化servlet过滤器init param。这有效地将servlet过滤器定义移动到Spring中,在Spring中有更强大的外部化工具(例如:PropertyPlaceHolderConfigure、环境变量等) 我怎样才能为servlet做到这一点呢?听起来这正是您所需要的 Spring控制器实现 包装一个servlet实例,该实例 内部管理。这样一个包袱 除此之外,还不知道serv

我有一个无法修改的第三方servlet。它接受我想要外部化的
init参数
(来自web.xml)

我可以使用外部化servlet过滤器
init param
。这有效地将servlet过滤器定义移动到Spring中,在Spring中有更强大的外部化工具(例如:PropertyPlaceHolderConfigure、环境变量等)

我怎样才能为servlet做到这一点呢?

听起来这正是您所需要的

Spring控制器实现 包装一个servlet实例,该实例 内部管理。这样一个包袱 除此之外,还不知道servlet 控制器;它的整个生命周期是 这里有


/WEB-INF/struts-config.xml

这将使您能够像对待其他Spring控制器一样对待遗留servlet,因此您可以使用普通的Spring MVC处理程序映射来路由到它。

看起来您需要一个
DelegatingServletProxy
类,尽管Spring中不存在这个类,但我认为编写代码非常简单,使用DelegatingFilterProxy作为起点

servlet只实现少数几个具体方法,因此委派应该是简单的

好吧,我把钱放在嘴边了! 编辑:下面是
DelegatingServletProxy
的基本实现

您可以这样使用它:

  • 在web.xml中设置常用的spring上下文配置/ContextListener,为您的webapp设置应用程序范围的spring上下文
  • 将servlet添加到web.xml中,其实现类是此DelegatingServletProxy。这将替换要更改其初始参数的现有serlvet。为这个新servlet设置init参数:proxyServletClass是servlet的类的名称。proxyServletParams是spring配置中的属性bean的名称。这个属性bean用于设置代理servlet的init参数
  • 在spring配置中,添加一个定义init参数的新Properties bean
  • spring应用程序上下文中的一些示例

    <bean name="myInitParams" class="java.util.Properties">
       <constructor-arg>
       <props>
            <prop key="initParamName">initParamValue</prop>
       </props>
       </constructor-arg>
    </bean>
    
    下面是servlet代码,它相当长,但大部分是委托
    ServletContext
    ——有趣的事情发生在顶部。这是未经测试的-应该被视为一个起点

    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServlet;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.Properties;
    import java.util.Set;
    
    public class DelegatingServletProxy extends HttpServlet implements WebApplicationContextAware
    {
        private HttpServlet delegate;
    
        private Properties initParams;
        private String delegateName;
    
        public void setDelegateName(String delegateName)
        {
            this.delegateName = delegateName;
        }
    
        public void init(ServletConfig config) throws ServletException
        {
            super.init(config);
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
            delegate = wac.getBean(delegateName, HttpServlet.class);
            delegate.init(new WrapServletConfig(config));
        }
    
        @Override
        public void destroy()
        {
            delegate.destroy();
        }
    
        @Override
        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
        {
            delegate.service(req, res);
        }
    
        public void setInitParams(Properties initParams)
        {
            this.initParams = initParams;
        }
    
        private class WrapServletConfig implements ServletConfig, ServletContext
        {
            // we override ServletContext also because it exposes getInitParameterNames()/getInitParemter()
            private ServletConfig delegate;
            private ServletContext delegateContext;
            public WrapServletConfig(ServletConfig config)
            {
                this.delegate = config;
                this.delegateContext = config.getServletContext();
            }
    
            @Override
            public String getServletName()
            {
                return delegate.getServletName();
            }
    
            @Override
            public ServletContext getServletContext()
            {
                return delegate.getServletContext();
            }
    
            @Override
            public String getInitParameter(String s)
            {
                return initParams.getProperty(s);
            }
    
            @Override
            public Enumeration getInitParameterNames()
            {
                return initParams.propertyNames();
            }
    
            @Override
            public Object getAttribute(String s)
            {
                return delegateContext.getAttribute(s);
            }
    
            @Override
            public Enumeration getAttributeNames()
            {
                return delegateContext.getAttributeNames();
            }
    
            @Override
            public void setAttribute(String s, Object o)
            {
                delegateContext.setAttribute(s, o);
            }
    
            @Override
            public void removeAttribute(String s)
            {
                delegateContext.removeAttribute(s);
            }
    
            @Override
            public String getServletContextName()
            {
                return delegateContext.getServletContextName();
            }
    
            // the remainer is just straight delegation to ServletContext
    
            @Override
            public ServletContext getContext(String s)
            {
                return delegateContext.getContext(s);
            }
    
            @Override
            public int getMajorVersion()
            {
                return delegateContext.getMajorVersion();
            }
    
            @Override
            public int getMinorVersion()
            {
                return delegateContext.getMinorVersion();
            }
    
            @Override
            public String getMimeType(String s)
            {
                return delegateContext.getMimeType(s);
            }
    
            @Override
            public Set getResourcePaths(String s)
            {
                return delegateContext.getResourcePaths(s);
            }
    
            @Override
            public URL getResource(String s)
                    throws MalformedURLException
            {
                return delegateContext.getResource(s);
            }
    
            @Override
            public InputStream getResourceAsStream(String s)
            {
                return delegateContext.getResourceAsStream(s);
            }
    
            @Override
            public RequestDispatcher getRequestDispatcher(String s)
            {
                return delegateContext.getRequestDispatcher(s);
            }
    
            @Override
            public RequestDispatcher getNamedDispatcher(String s)
            {
                return delegateContext.getNamedDispatcher(s);
            }
    
            @Override
            public Servlet getServlet(String s)
                    throws ServletException
            {
                return delegateContext.getServlet(s);
            }
    
            @Override
            public Enumeration getServlets()
            {
                return delegateContext.getServlets();
            }
    
            @Override
            public Enumeration getServletNames()
            {
                return delegateContext.getServletNames();
            }
    
            @Override
            public void log(String s)
            {
                delegateContext.log(s);
            }
    
            @Override
            public void log(Exception e, String s)
            {
                delegateContext.log(e, s);
            }
    
            @Override
            public void log(String s, Throwable throwable)
            {
                delegateContext.log(s, throwable);
            }
    
            @Override
            public String getRealPath(String s)
            {
                return delegateContext.getRealPath(s);
            }
    
            @Override
            public String getServerInfo()
            {
                return delegateContext.getServerInfo();
            }
        }
    }
    

    你如何使用这个作为替代品?它似乎没有实现Servlet接口。@mdma:没有,它是一个Spring控制器。servlet部分由标准的Spring
    DispatcherServlet
    处理,它将请求转发给控制器,然后控制器调用Spring管理的servlet。我一直在想为什么Spring不提供这样一个类。通常他们有很好的理由。。。
    <servlet>
       <servlet-name>...</servlet-name>
        <servlet-class>
            acme.DelegatingServletProxy
        </servlet-class>
        <init-param>
             <param-name>proxyServletClass</param-name>
             <param-value>your.original.servlet.ServletClass</param-value>
        </init-param>
        <init-param>
            <param-name>proxyServletParams</param-name>
            <param-value>myServletParams</param-value>
            <!-- name of bean in spring context -->
        </init-param>
    </servlet>
    
    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServlet;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.Properties;
    import java.util.Set;
    
    public class DelegatingServletProxy extends HttpServlet implements WebApplicationContextAware
    {
        private HttpServlet delegate;
    
        private Properties initParams;
        private String delegateName;
    
        public void setDelegateName(String delegateName)
        {
            this.delegateName = delegateName;
        }
    
        public void init(ServletConfig config) throws ServletException
        {
            super.init(config);
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
            delegate = wac.getBean(delegateName, HttpServlet.class);
            delegate.init(new WrapServletConfig(config));
        }
    
        @Override
        public void destroy()
        {
            delegate.destroy();
        }
    
        @Override
        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
        {
            delegate.service(req, res);
        }
    
        public void setInitParams(Properties initParams)
        {
            this.initParams = initParams;
        }
    
        private class WrapServletConfig implements ServletConfig, ServletContext
        {
            // we override ServletContext also because it exposes getInitParameterNames()/getInitParemter()
            private ServletConfig delegate;
            private ServletContext delegateContext;
            public WrapServletConfig(ServletConfig config)
            {
                this.delegate = config;
                this.delegateContext = config.getServletContext();
            }
    
            @Override
            public String getServletName()
            {
                return delegate.getServletName();
            }
    
            @Override
            public ServletContext getServletContext()
            {
                return delegate.getServletContext();
            }
    
            @Override
            public String getInitParameter(String s)
            {
                return initParams.getProperty(s);
            }
    
            @Override
            public Enumeration getInitParameterNames()
            {
                return initParams.propertyNames();
            }
    
            @Override
            public Object getAttribute(String s)
            {
                return delegateContext.getAttribute(s);
            }
    
            @Override
            public Enumeration getAttributeNames()
            {
                return delegateContext.getAttributeNames();
            }
    
            @Override
            public void setAttribute(String s, Object o)
            {
                delegateContext.setAttribute(s, o);
            }
    
            @Override
            public void removeAttribute(String s)
            {
                delegateContext.removeAttribute(s);
            }
    
            @Override
            public String getServletContextName()
            {
                return delegateContext.getServletContextName();
            }
    
            // the remainer is just straight delegation to ServletContext
    
            @Override
            public ServletContext getContext(String s)
            {
                return delegateContext.getContext(s);
            }
    
            @Override
            public int getMajorVersion()
            {
                return delegateContext.getMajorVersion();
            }
    
            @Override
            public int getMinorVersion()
            {
                return delegateContext.getMinorVersion();
            }
    
            @Override
            public String getMimeType(String s)
            {
                return delegateContext.getMimeType(s);
            }
    
            @Override
            public Set getResourcePaths(String s)
            {
                return delegateContext.getResourcePaths(s);
            }
    
            @Override
            public URL getResource(String s)
                    throws MalformedURLException
            {
                return delegateContext.getResource(s);
            }
    
            @Override
            public InputStream getResourceAsStream(String s)
            {
                return delegateContext.getResourceAsStream(s);
            }
    
            @Override
            public RequestDispatcher getRequestDispatcher(String s)
            {
                return delegateContext.getRequestDispatcher(s);
            }
    
            @Override
            public RequestDispatcher getNamedDispatcher(String s)
            {
                return delegateContext.getNamedDispatcher(s);
            }
    
            @Override
            public Servlet getServlet(String s)
                    throws ServletException
            {
                return delegateContext.getServlet(s);
            }
    
            @Override
            public Enumeration getServlets()
            {
                return delegateContext.getServlets();
            }
    
            @Override
            public Enumeration getServletNames()
            {
                return delegateContext.getServletNames();
            }
    
            @Override
            public void log(String s)
            {
                delegateContext.log(s);
            }
    
            @Override
            public void log(Exception e, String s)
            {
                delegateContext.log(e, s);
            }
    
            @Override
            public void log(String s, Throwable throwable)
            {
                delegateContext.log(s, throwable);
            }
    
            @Override
            public String getRealPath(String s)
            {
                return delegateContext.getRealPath(s);
            }
    
            @Override
            public String getServerInfo()
            {
                return delegateContext.getServerInfo();
            }
        }
    }