1

I am developing web application using spring mvc. I want to inject spring beans into my Servlet Filter.

I refered this tutorial http://www.deadcoderising.com/2015-05-04-dependency-injection-into-filters-using-delegatingfilterproxy/

Following is my file listing

    @Component("auditFilter")
    public class AuditFilter implements Filter {

        @Autowired
        private AuditHandler auditHandler;

        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            System.out.println("do filter");
            auditHandler.auditRequest(req);
            chain.doFilter(req, res);
        }

        public void init(FilterConfig filterConfig) throws ServletException {
        }

        public void destroy() {
        }
    }

@Component("auditHandler")
public class AuditHandler {

    public void auditRequest(ServletRequest request) {
        System.out.println("Received request from " + request.getRemoteAddr());
    }
}

@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);

        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

        String formattedDate = dateFormat.format(date);

        model.addAttribute("serverTime", formattedDate );

        return "home";
    }

}

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing 
        infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <context:component-scan base-package="com.xyz.springtest" />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
        up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
        in the /WEB-INF/views directory -->
    <beans:bean


class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <beans:property name="prefix" value="/WEB-INF/views/" />
            <beans:property name="suffix" value=".jsp" />
        </beans:bean>
    </beans:beans>

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

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

    <filter>  
        <filter-name>auditFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
        <init-param>
            <param-name>appName</param-name>
            <param-value>di-example</param-value>
        </init-param>
    </filter>

</web-app>

When I start my application I get following exception

SEVERE: Exception starting filter auditFilter
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'auditFilter' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:277)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1097)
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:236)
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

What I am missing?

following posts didnt help me

@Autowired in DelegatingFilterProxy

How can I get a Spring bean in a servlet filter?

Spring Framework filter, bean not injected

Spring and @Autowired on a DelegatingFilterProxy

Community
  • 1
  • 1
Javadroider
  • 2,280
  • 1
  • 22
  • 45

1 Answers1

2

you have to load your beans in 'root-context.xml', it where the application context beans loaded.

your 'servlet-context.xml' loads WebApplicationContext, so define your mvc controllers here, other beans if you want to access application wide, should be moved to your root application context. There is one root context for your application, but there can be many application contexts, (for each dispatcher servlet.). Beans in spring-servlet.xml can reference beans in root application context, but not vice versa

define your beans in 'root-context.xml'

kuhajeyan
  • 10,727
  • 10
  • 46
  • 71
  • Really? Shouldn't contextConfigLocation make it point to the correct xml file? – Florian Schaetz Aug 20 '16 at 16:48
  • @FlorianSchaetz http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html "A web application can define any number of DispatcherServlets. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context as loaded by ContextLoaderListener, if any, will be shared." – kuhajeyan Aug 20 '16 at 16:56
  • I was able to get auditFilter instance after defining it in root-context.xml. But I am not getting beans which I have defined in 'servlet-context.xml' – Javadroider Aug 21 '16 at 05:17
  • @Javadroider why should not you move move your 'root-context.xml' http://stackoverflow.com/questions/11708967/what-is-the-difference-between-applicationcontext-and-webapplicationcontext-in-s – kuhajeyan Aug 22 '16 at 04:56
  • Beans in spring-servlet.xml can reference beans in root-context.xml, but not vice versa. – kuhajeyan Aug 22 '16 at 05:12