2010-05-16 12 views
5

Tengo un servlet de terceros que no puedo modificar. Acepta un init-param que me gustaría externalizar (desde web.xml).Cómo externalizar web.xml servlet init-param? Spring DelegatingFilterProxy para Servlets?

puedo exteriorizar un filtro de servlet init-param usando DelegatingFilterProxy. Esto mueve efectivamente la definición del filtro de servlet a Spring, donde hay herramientas de externalización mucho más potentes (por ejemplo: PropertyPlaceholderConfigurer, variables de entorno, etc.)

¿Cómo puedo hacer esto para un servlet?

Respuesta

2

Suena como ServletWrapperController es lo que necesita.

aplicación Controlador de primavera que envuelve una instancia de servlet que se administra en su interior. Tal servlet envuelto no se conoce fuera de este controlador ; la totalidad de su ciclo de vida se cubre aquí

<bean id="strutsWrappingController" class="org.springframework.web.servlet.mvc.ServletWrappingController"> 
    <property name="servletClass" value="org.apache.struts.action.ActionServlet"/> 
    <property name="servletName" value="action"/> 
    <property name="initParameters"> 
    <props> 
     <prop key="config">/WEB-INF/struts-config.xml</prop> 
    </props> 
    </property> 
</bean> 

Esto le permitirá tratar el servlet legado como otro controlador de primavera, por lo que el uso normal asignaciones de controlador Spring MVC para ir a ella.

+0

¿cómo se usa esto como una sustitución? No parece implementar la interfaz Servlet. – mdma

+0

@mdma: No, es un controlador de Spring. La parte de servlet es manejada por el estándar Spring 'DispatcherServlet', que reenvía la solicitud al controlador, que luego invoca su servlet administrado por Spring. – skaffman

5

Parece que necesita una clase DelegatingServletProxy, aunque esto no existe en la primavera Sin embargo, me imagino que es bastante sencillo de código, usando DelegatingFilterProxy como un punto de partida.

Un servlet implementa solamente un puñado de métodos concretos, por lo que la delegación debe ser sencillo.

Ok, puse mi dinero donde está mi boca! EDIT: A continuación una implementación básica de DelegatingServletProxy.

que lo utilice como esto:

  1. de configuración del contexto habitual de primavera de configuración/ContextListener en web.xml para establecer el contexto de primavera en toda la aplicación para su aplicación web.
  2. Agregue un servlet a su web.xml cuya clase de implementación sea DelegatingServletProxy. Esto reemplaza su servidor existente para el que desea cambiar los parámetros de inicio. Establece los parámetros init para este nuevo servlet: proxyServletClass es el nombre de la clase de su servlet. proxyServletParams es el nombre de un bean de propiedades en su configuración de primavera. Este bean de propiedades se usa para establecer los params init para el servlet proxy.
  3. En su config primavera, añadir un nuevo Properites bean que define el init-params

algunos ejemplos, en el contexto de aplicación de resorte

<bean name="myInitParams" class="java.util.Properties"> 
    <constructor-arg> 
    <props> 
     <prop key="initParamName">initParamValue</prop> 
    </props> 
    </constructor-arg> 
</bean> 

Ejemplo web.xml snippet

<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> 

Aquí está el código del servlet, es bastante largo, pero la mayor parte está delegando ServletContext - sucede lo interesante en la cima. No se ha probado, debe considerarse un punto de partida.

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(); 
     } 
    } 
} 
+0

Hace tiempo que me pregunto por qué Spring no brinda esa clase. Por lo general, tienen buenas razones ... –

Cuestiones relacionadas