Announcement Announcement Module
Collapse
No announcement yet.
Howto: The joy that is DelegatingFilterProxy Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Howto: The joy that is DelegatingFilterProxy

    As requested by another user; let me share the love for DelegatingFilterProxy

    The problem is that you have filters which require collaborators. Those collaborators are managed by Spring. Hmm, what do you do?

    Assume:

    Code:
      interface Collaborator {
        boolean canIProceed();
      }
    
      public final class MyFilter implements Filter {
        private Collaborator collaborator;
        ////
      }
    How do you wire these up? If you are a simpleton like me you would have some code like this:

    Code:
    public class CollaboratorAwareFilter extends GenericFilterBean {
    	private Collaborator collaborator;
    
    	protected final void initFilterBean() throws ServletException {
    		super.initFilterBean();
    		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
    		collaborator = (Collaborator) wac.getBean("collaborator");
    	}
    
    	protected final Collaborator getCollaborator() {
    		return collaborator;
    	}
    }
    Immediately the code becomes incredibly fragile (looking up by strings) and very difficult to test.

    (To the fanfare of trumpets) DelegatingFilterProxy comes to our rescue. It basically is a filter which will delegate to a filter retrieved from the current applicationContext.

    In other words, I have a filter that looks like:
    Code:
      public class MyFilter implements Filter {
        private final Collaborator collaborator;
        public MyFilter(final Collaborator theCollaborator) {
          this.collaborator = theCollaborator;
        }
        ...
      }
    I have a "filters-context.xml":
    Code:
      <bean id="myFilter" class="uk.mycompany.MyFilter">
        <constructor-arg index="0" ref="collaborator"/>
      </bean>
    and in web.xml:

    Code:
      <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
    Note: DelegatingFilterProxy will use the value filter-name as the name of the bean. If this does not suit, you can provide the name of the bean via the "targetBeanName" parameter.

    Yeah for Spring

    HTH

  • #2
    Filter Never Getting Invoked

    Hi,
    I have lot of filters to implement in Spring MVC. Initially, as suggested in your blog, I tried doing a test filter as below.

    In my web.xml:

    <filter>
    <filter-name>testFilter</filter-name>
    <display-name>Test Filter</display-name>
    <description>Test Filter</description>
    <filter-class>org.springframework.web.filter.DelegatingFil terProxy</filter-class>
    </filter>

    <filter-mapping>
    <filter-name>testFilter</filter-name>
    <url-pattern>/voicelet/*</url-pattern>
    </filter-mapping>

    In applicationContext-Service.xml:

    <bean id="testFilter" class="com.amfam.voice.app.src.access.TestFilter">
    </bean>

    With the above code, the doFilter() in TestFilter.java is never getting invoked.

    Any kind of help would be very much great ful. Please let me know, if I need to do any more configuration changes. Thanks in advance. Could you please reply.

    FYI. The TestFilter.java is as below.

    /*
    * Created on Apr 14, 2008
    *
    * To change the template for this generated file go to
    * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
    */
    package com.amfam.voice.app.src.access;

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;

    import java.io.IOException;
    import javax.servlet.ServletException;

    public class TestFilter implements Filter
    {
    private FilterConfig filterConfig;

    public void doFilter (ServletRequest request,
    ServletResponse response,
    FilterChain chain)
    {

    try
    {
    System.out.print ("Within Simple Filter ... ");
    System.out.println ("Filtering the Request ...");

    chain.doFilter (request, response);

    System.out.print ("Within Simple Filter ... ");
    System.out.println ("Filtering the Response ...");

    } catch (IOException io) {
    System.out.println ("IOException raised in SimpleFilter");
    } catch (ServletException se) {
    System.out.println ("ServletException raised in SimpleFilter");
    }
    }

    public FilterConfig getFilterConfig()
    {
    return this.filterConfig;
    }

    public void setFilterConfig (FilterConfig filterConfig)
    {
    this.filterConfig = filterConfig;
    }

    /* (non-Javadoc)
    * @see javax.servlet.Filter#init(javax.servlet.FilterConf ig)
    */
    public void init(FilterConfig arg0) throws ServletException {
    // TODO Auto-generated method stub
    System.out.print ("Within Init Filter...");

    }

    /* (non-Javadoc)
    * @see javax.servlet.Filter#destroy()
    */
    public void destroy() {
    // TODO Auto-generated method stub

    }
    }

    Comment


    • #3
      any luck with this rtavva
      have you tried Specifying the "targetFilterLifecycle" filter init-param as "true" in web.xml

      Comment


      • #4
        DelegatingFilterProxy

        Hi,
        Yes. I was able to resolve the problem. Thanks for asking.

        The main reason for our problem was one of our team members made some changes to 'ibm-web-bnd.xmi' which are not at all needed. Looks like, the person made these changes so that the application locates some wav files. With these changes in place, even the simple servlet filter was not getting called.

        I removed the unnecessary changes from 'ibm-web-bnd.xmi' and the filter started working very much fine.

        All I needed was to simply follow the steps in this parent thread(Howto: The joy that is DelegatingFilterProxy ) and every thing ran greatly.

        Regards,
        Raghav.

        Comment


        • #5
          Wonderful tip Colin. I stumbled on it accidentally, and on research found this post.

          Originally posted by Colin Yates View Post

          Yeah for Spring

          HTH
          +1

          Comment


          • #6
            hi, i'm trying to do some logging into my database from inside a filter using hibernate. therefore i have an abstract org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean and a couple of child beans:


            Code:
            	<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
            		<property name="transactionManager" ref="transactionManager"/>
            		<property name="transactionAttributes">
            			<props>
            				<prop key="save">PROPAGATION_REQUIRED</prop>
            				<prop key="delete">PROPAGATION_REQUIRED</prop>
            				<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            			</props>
            		</property>
            	</bean>
            
            	<bean id="userDaoTarget" class="com.example.dao.UserDao">
            		<property name="sessionFactory" ref="sessionFactory"></property>
            	</bean>
            	
            	<bean id="userDao" parent="baseTransactionProxy">
            		<property name="target" ref="userDaoTarget"/>
            	</bean>
            When using the above mentioned method to pass the bean "userDao" to the filter, i get the following exception:

            Code:
            Error creating bean with name 'loggingFilter' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.example.dao.LogDao]: Could not convert constructor argument value of type [$Proxy10] to required type [com.example.dao.LogDao]: Failed to convert value of type [$Proxy10 implementing com.example.dao.ILogDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.example.dao.LogDao]; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy10 implementing com.example.dao.ILogDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.example.dao.LogDao]: no matching editors or conversion strategy found
            When injecting the userDao into my service beans, spring does not give me any error about the proxy stuff.

            Anyone knows how to solve this ?

            thanks !

            Comment

            Working...
            X