forreg
forreg

Reputation: 3

Spring dependency config problems

Hello guys,

I am new to Spring and currently I am working on a web project in which I use Spring MVC and Spring dependency injection. I have three classes. UserService, HomeController and User. In HomeController I invoke UserService's fetchUser method which returns me a new Instance of the User class. It is a simple logic I use to reproduce my real project problem. I am not using any database in this simple project. When I invoke the fetchUserMethod I am getting a NullPointerException. I am using Glassfish 4.0. Could you please help me ? Thank you !

Here is my 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/aplicationContext.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/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>

        </web-app>`

Here is my applicationContext.xml

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

            <!-- Root Context: defines shared resources visible to all other web components -->

            <bean id="userService" class="services.UserService"/>

            <bean id="homeController" class="controllers.HomeController">
                <property name="userService" ref="userService"/>
            </bean>

        </beans>

Here is my servlet-context.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <beans:beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc" 
        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">


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

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

        <context:component-scan base-package="controllers"/>

    </beans:beans>

Here is my HomeController class

@Controller
public class HomeController {

    private UserService userService;

    @RequestMapping(value = "/home")
    public ModelAndView homePage(HttpServletRequest request, HttpServletResponse response, HttpSession session){



        User user = userService.fetchUser();

        return new ModelAndView("home", "displayName", user.getUserName());
    }

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

}

Here is my User class

public class User {

    private String userName;

    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

Here is my UserService class

public class UserService {


    public User fetchUser(){

        User user = new User();
        user.setUserName("test");

        return user;
    }
}

Upvotes: 0

Views: 82

Answers (3)

forreg
forreg

Reputation: 3

This way Eclipse marks the default constructor line with error. If I remove the default constructor glassfish says it cannot initialize UserService because there is no default constructor.

public class UserService {

public UserService(){}

private final UserDao userDao;

@Autowired
public UserService(UserDao userDao){
    this.userDao = userDao;
}


public User fetchUser(){

    User user = userDao.fetchUser();

    return user;
}

}

Upvotes: 0

Maciej Walkowiak
Maciej Walkowiak

Reputation: 12932

  1. Remove homeController bean defintiion.

Since you are using <context:component-scan base-package="controllers"/> there is no need to declare homeController bean - it will be created automatically because it's annotated with annotation @Controller.

  1. Autowire UserService into HomeController using@Autowired` annotation. There are 3 ways you can do it:
    • field injection:
@Autowired
private UserService userService;
  • setter injection
@Autowired
public void setUserService(UserService userService) {
    this.userService = userService;
}
  • constructor injection:
@Autowired
public HomeController(UserService userService) {
    this.userService = userService;
}

Preferred way is to always use constructor injection

  1. Remove UserService getters and setters in HomeController.

In the end, HomeController class should look like:

@Controller
public class HomeController {
    private final UserService userService;

    @Autowired
    public HomeController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value = "/home")
    public ModelAndView homePage(HttpServletRequest request, HttpServletResponse response, HttpSession session){
        User user = userService.fetchUser();

        return new ModelAndView("home", "displayName", user.getUserName());
    }
}

Upvotes: 0

Jens
Jens

Reputation: 69440

You miss the @Autowired annotation in your HomeController:

@Autowired
private UserService userService;

Upvotes: 1

Related Questions