How to externalize the web.xml of the init-param servlet? Spring DelegatingFilterProxy for servlet?

I have a third-party servlet that I cannot change. It accepts init-param , which I would like to do as externalization (from web.xml).

I can filter the init-param servlet filter using DelegatingFilterProxy . This effectively translates the definition of a servlet filter into Spring, where there are much more powerful externalization tools (e.g. PropertyPlaceholderConfigurer, environment variables, etc.).

How to do this for a servlet?

+6
java spring servlets
source share
2 answers

It looks like you need the DelegatingServletProxy class, although this does not exist in Spring However, I think it is quite simple to use the DelegatingFilterProxy code as a starting point.

Servlet implements only a few specific methods, so delegation should be simple.

Ok, I put my money where my mouth is! EDIT: Below is the base implementation of DelegatingServletProxy .

You use it as follows:

  • Set the usual Spring / ContextListener context configuration to web.xml to set the Spring context for your entire web page.
  • Add the servlet to your web.xml whose implementation class is DelegatingServletProxy. This replaces your existing serlvet for which you want to modify init-params. You set the init parameters for this new servlet: proxyServletClass is the class name of your servlet. proxyServletParams is the name of the bean property in the Spring configuration. These bean properties are used to set the init parameters for the proxied servlet.
  • In the Spring configurator, add a new Properites bean that defines init-params

Some examples in the context of a Spring application

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

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

Here is the servlet code, it is quite long, but most of it is delegated by ServletContext - interesting material comes from above. It is untested - it should be considered a starting point.

 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(); } } } 
+6
source share

Sounds like ServletWrapperController - this is what you need.

Spring An implementation of a controller that wraps an instance of a servlet that it manages internally. Such a wrapped servlet is not known outside of this controller; his whole life cycle is here.

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

This will allow you to relate to an outdated servlet, as well as to another Spring controller, so you use the usual Spring MVC handler mappings to route it.

+2
source share

All Articles