3
votes

I'm trying to simply try out Spring, yet I seem to be missing something. It seems to load Spring and the beans just fine, however when it comes to injecting those beans with autowired, it doesn't work. Does anybody have a clue?

The part for of web.xml for Spring and the mainServlet:

    <welcome-file-list>
        <welcome-file>/login.jsp</welcome-file>
    </welcome-file-list>

    <!-- Spring Dependency Injection -->

     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

  <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
    </listener-class>

<!-- Login Filter -->
<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.nortal.pirs.presentation.web.LoginFilter</filter-class>
    <init-param>
        <param-name>secretParameter</param-name>
        <param-value>8392</param-value>
    </init-param>
</filter>

<filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/MainServlet</url-pattern>
        <servlet-name>MainServlet</servlet-name>
</filter-mapping>

<!-- Main Servlet -->
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>com.nortal.pirs.presentation.web.MainServlet</servlet-class>

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/main/*</url-pattern>
</servlet-mapping>

Spring application context file (Though I think I also loaded it with too much unnecessary crap, but it was out of desperation because it wasn't working):

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

    <context:annotation-config />

    <!-- Turn on AspectJ @Configurable support -->
    <context:spring-configured />

    <context:component-scan base-package="com.nortal.pirs.test.independent" />
    <context:component-scan base-package="com.nortal.pirs.businesslogic.logic" />
    <context:component-scan base-package="com.nortal.pirs.presentation.vaadin" />
    <context:component-scan base-package="com.nortal.pirs.presentation.vaadin.views" />
    <context:component-scan base-package="com.nortal.pirs.presentation.web" />

    <!-- Turn on @Autowired, @PostConstruct etc support -->
    <bean
        class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
    <bean
        class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />

</beans>

UserManagerLogic (The bean that has to be injected in MainServlet with @autowired later):

@Component("UserManager")
public class UserManagerLogic implements UserManagerInterface {

MainServlet:

 @Service
public class MainServlet extends HttpServlet {

    @Autowired
    @Qualifier("UserManager")
    private UserManagerInterface userManager;
    Logger log;

    public MainServlet() {
        log = Logger.getLogger(getClass());
    }

    public boolean userLoggedIn(String username, String password) {     
        return SecurityManager.getInstance().credentialsValid(username, password);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        processRequest(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        processRequest(req, resp);
    }

    public void processRequest(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {

        HttpSession session = ((HttpServletRequest) request).getSession();

        String username = (String) session.getAttribute("username");
        boolean authenticated = (boolean) session.getAttribute("authenticated");

        User user = userManager.getUserByEmail(username);

        WelcomeGenerator welcomeGenerator = new WelcomeGenerator();

        if (authenticated) {
            generateResponse(response, welcomeGenerator.WelcomeMessage(user), "The secret code is " + session.getAttribute("secretParameter"));
        } else {
            generateResponse(response, welcomeGenerator.wrongCredentialsMessage(username), "Secret code is hidden, because authentication failed");
        }
    }

    public void generateResponse(HttpServletResponse response, String welcomeMessage, String additionalData) throws IOException {       
        HtmlGenerator generator = new HtmlGenerator("PIRS");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.write(generator.printHeader());
        out.write(generator.printCenter(welcomeMessage));
        out.write(generator.printCenter(additionalData));
        out.write(generator.printFooter());
    }

    public UserManagerInterface getUserManager() {
        return userManager;
    }

    public void setUserManager(UserManagerInterface userManager) {
        this.userManager = userManager;
    }               
}

And the outcome is a null pointer exception on the call for userManager of course, which was supposed to be injected by Spring?

java.lang.NullPointerException
    at com.nortal.pirs.presentation.web.MainServlet.processRequest(MainServlet.java:58)
    at com.nortal.pirs.presentation.web.MainServlet.doPost(MainServlet.java:47)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)

However Spring does load the beans it only doesn't inject them and doesn't throw any error, why is that?

2013-03-08 03:48:42,834 [localhost-startStop-1] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6a4ac9fb: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.config.internalBeanConfigurerAspect,mainController,SecurityManager,**UserManager**,VisitManager,**mainServlet**,org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#0,org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
2
why don't you use a controller instead of servletArun P Johny
@service annotation is not meant for a servlet.Check this out.Should be same issue as yours .stackoverflow.com/questions/14283750/…SRy

2 Answers

1
votes

Your servlet isn't @Configurable. Since its lifecycle isn't controlled by Spring, that's the only way you're going to get it to be autowired.

Oh, and your servlet definitely isn't a @Service.

0
votes

Thats because Servlets are managed by Spring Container. Servlets are managed by the Servlet Container.

But fortunately Spring provides an utility method to get hold of SpringApplicationContext to get beans from the Servlet. This is accomplished using WebApplicationContextUtils

Sample Code

ApplicationContext ctx = 
                    WebApplicationContextUtils.
                          getWebApplicationContext(session.getServletContext());
UserManagerInterface userManager = (UserManagerInterface )ctx.getBean("UserManager");