1

I am using Spring DI and trying to inject a Spring service in my servlet. However, it isn't injected and stays null, causing NullPointerException.

My servlet:

@WebServlet(urlPatterns = {"/Register"}, displayName = "RegisterServlet")
public class RegisterServlet extends HttpServlet {

    @Autowired
    @Qualifier("registerServlet")
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // ...
        customerService.save(customer); // Fail, because service is null.
        // ...
    }

}

My spring-controller.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">

    <bean id="registerServlet" class="com.fishingstore.controller.RegisterServlet">
        <property name="customerService" ref="customerService"/>
    </bean>

</beans>

My Customer DAO class:

@Repository
@Transactional
public class CustomerDAOImpl implements CustomerDAO {

    private SessionFactory sessionFactory;

    @Autowired
    @Qualifier("sessionFactory")
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // ...
}

My Customer service class:

@Service
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    @Qualifier("customerService")
    private CustomerDAO customerDAO;

    // ...
}

My spring-service.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">

    <bean id="customerService" class="com.fishingstore.service.implementation.CustomerServiceImpl">
        <property name="customerDAO" ref="customerDAO"/>
    </bean>
</beans>

Where is my mistake?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Kirk_Hammett
  • 63
  • 1
  • 10
  • You are using `registerServlet` qualifier to inject `CustomerService` bean in your servlet. Is that correct, I suspect. – Madhusudana Reddy Sunnapu Feb 07 '16 at 15:22
  • I'm inject bean in my servlet without @Qualifier, it's doesn't work – Kirk_Hammett Feb 07 '16 at 16:12
  • Do not ask why you got a `NullPointerException`. [Every Java developer knows the answer to that](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it). Instead ask why a given variable is `null`. I reduced irrelevant code from the question to make it better focused. – BalusC Feb 07 '16 at 16:14
  • BalusC, Thanks, you are right, I incorrectly formulated my question. I will be more attentive. – Kirk_Hammett Feb 07 '16 at 16:22

2 Answers2

5

Servlets are not managed by Spring Container. So apparently any @Autowired annotations in that class will not be processed.

Spring provides two static methods in the class SpringBeanAutowiringSupport
which can be used in the the servlet classes to enable Autowiring feature.

  1. processInjectionBasedOnCurrentContext(Object target)
  2. processInjectionBasedOnServletContext(Object target, ServletContext servletContext)

An example using the first method is here and for the second method is here

The idea behind the two approaches is to override the Servlet's init method and enable the autowiring of beans.

For example -

@Override
    public void init(ServletConfig config) throws ServletException{
        super.init(config);
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

    }

Make sure you autowire the beans correctly as pointed out in @Reimeus answer.

Omkar Puttagunta
  • 4,036
  • 3
  • 22
  • 35
2

Change the CustomerService qualifier to match the bean id or better remove @Qualifier entirely

@Autowired
@Qualifier("customerService")
public void setCustomerService(CustomerService customerService) {

Do the same for customerDAO

@Autowired
@Qualifier("customerDAO")
private CustomerDAO customerDAO;
Reimeus
  • 158,255
  • 15
  • 216
  • 276