Lỗi khi xài ContextLoaderListener trong Spring MVC

Mình có 1 project sử dụng Spring MVC 3 + Hibernate 4, trong file web.xml khi mình bỏ ContextLoaderListener vào thì lập tức khi chạy sẽ bị lỗi “Error 404 - The requested resource is not available”, báo lỗi ngay file index.jsp. Còn nếu mình không sử dụng ContextLoaderListener thì vẫn chạy được bình thường, nhưng có thể không xài được các bean được khai báo trong file applicationContext.xml.

Đây là nội dung các file:
web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>ATJB_Assignment6_SecondApproach</display-name>
    
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.web</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml
        </param-value>
    </context-param>
    
    <welcome-file-list>
        <welcome-file>redirect.jsp</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx" 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
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop/ http://www.springframework.org/schema/aop/spring-aop.xsd">

    <mvc:annotation-driven />
    <context:component-scan base-package="com.nddkhang" />
    
    <context:property-placeholder location="classpath:config.properties" />

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager"
        p:sessionFactory-ref="sessionFactory" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
        <property name="packagesToScan" value="com.fpt.contact.entities">
        </property>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
        p:username="${jdbc.username}" p:password="${jdbc.password}" />

    <!-- Bean configuration -->
    <bean id="courseDao" class="com.nddkhang.dao.CourseDAOImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="feedbackDao" class="com.nddkhang.dao.FeedbackDAOImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="traineeDao" class="com.nddkhang.dao.TraineeDAOImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

config.properties

# database properties
app.jdbc.driverClassName=com.mysql.jdbc.Driver
app.jdbc.url=jdbc:mysql://localhost:3306/trainees
app.jdbc.username=root
app.jdbc.password=lulu

#hibernate properties
hibernate.config=/WEB-INF/hibernate.cfg.xml


################### JDBC Configuration ##########################
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/trainees

jdbc.username=root
jdbc.password=lulu

#################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
#hibernate.hbm2ddl.auto=update
hibernate.generate_statistics=true

dispatcher-servlet.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" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="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
        http://www.springframework.org/schema/mvc  
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven />
    <context:component-scan base-package="com.nddkhang.controller" />

    <!-- Declare a view resolver -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

    <!-- Configure the multipart resolver -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>
</beans>

TraineeController

package com.nddkhang.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.nddkhang.dao.FeedbackDAO;
import com.nddkhang.dao.TraineeDAO;
import com.nddkhang.entities.Trainee;

/**
 * The Class TraineeController.
 */
@Repository
@Controller
public class TraineeController {

    /** The trainee dao. */
    @Autowired
    private TraineeDAO traineeDao;

    /** The course dao. */
    // @Autowired
    // private CourseDAO courseDao;

    /** The feedback dao. */
    @Autowired
    private FeedbackDAO feedbackDao;

    /** The accounts. */
    private Object accounts = null;

    /** The courses. */
    // private Object courses = null;

    /** The feedbacks. */
    private Object feedbacks = null;

    /** The current trainee. */
    private Trainee currentTrainee = new Trainee();

    /** The message. */
    private StringBuffer message = new StringBuffer();

    /** The rate. */
    // private String[] rate = { "Strongly disagree", "Disagree", "Neutral ",
    // "Agree ", "Strongly agree" };

    /**
     * Login form.
     *
     * @return the string
     */
    @RequestMapping(value = { "/loginForm", "/", "/home", "/index" }, method = RequestMethod.GET)
    public String loginForm() {
        return "loginForm";
    }

    /**
     * Process login page.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     * @param model
     *            the model
     * @return the string
     */
    @RequestMapping(value = "/login", params = "btnAction", method = RequestMethod.POST)
    public String processLoginPage(HttpServletRequest request, @RequestParam Map<String, String> reqPar,
            HttpSession session, ModelMap mm) {
        message.setLength(0); // Clear message

        String accountName = reqPar.get("accountName");
        String email = reqPar.get("email");

        if (traineeDao.getTraineeByEmail(email) != null) {
            if (traineeDao.getTraineeByEmail(email).getAccountName().equals(accountName)) {
                currentTrainee = traineeDao.getTraineeByEmail(email);
                accounts = traineeDao.getAllTrainees();

                session = request.getSession();
                session.setAttribute("currentTrainee", currentTrainee);

                feedbacks = feedbackDao.getAllFeedbackByTrainee(currentTrainee.getId());
                mm.put("feedbacks", feedbacks);
                mm.put("accounts", accounts);
            }
        } else {
            message.append("Wrong account name or e-mail");
            mm.put("message", message);
            return "loginForm";
        }

        return "traineeList";
    }

    @RequestMapping(value = "/login.web", params = "btnDirect", method = RequestMethod.POST)
    public String direct2RegisterPage(HttpServletRequest request, @RequestParam Map<String, String> reqPar) {
        return "registerPage";
    }
}

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="com.nddkhang.*"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login Page</title>
</head>
<body>
    <h3 style="color: #E50A0A;">${message}</h3>

    <h2 align="center">Welcome to FPT Login Page</h2>
    <form action="login.web" name="myLoginForm" method="post">
        <div align="center">
            <table>
                <tr>
                    <td align="right">Account Name:</td>
                    <td><input type="text" name="accountName" required /></td>
                </tr>

                <tr>
                    <td align="right">E-mail:</td>
                    <td><input type="email" name="email" required /></td>
                </tr>

                <tr>
                    <td align="right"><input type="submit" value="Login"
                        name="btnAction" /></td>
                    <td><input type="reset" value="Reset" /> <input type="submit"
                        value="Register" formnovalidate name="btnDirect" /></td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>

TraineeDAO

package com.nddkhang.dao;

import java.util.List;

import org.springframework.stereotype.Component;

import com.nddkhang.entities.Trainee;

/**
 * @author ND2K
 *
 */
@Component
public interface TraineeDAO {

    /**
     * Save trainee.
     *
     * @param trainee
     *            the trainee
     */
    void saveTrainee(Trainee trainee);

    /**
     * Update trainee.
     *
     * @param trainee
     *            the trainee
     */
    void updateTrainee(Trainee trainee);

    /**
     * Gets the all trainees.
     *
     * @return all trainees
     */
    List<Trainee> getAllTrainees();

    /**
     * Gets the trainee.
     *
     * @param id
     *            the id
     * @return trainee with specific Id
     */
    Trainee getTrainee(int id);

    /**
     * Gets the trainee by email.
     *
     * @param email
     *            the email
     * @return trainee by email
     */
    Trainee getTraineeByEmail(String email);

    /**
     * Check email exist.
     *
     * @param email
     *            the email
     * @return true, if successful
     */
    boolean checkEmailExist(String email);

    /**
     * Check account name exist.
     *
     * @param accountName
     *            the account name
     * @return true, if successful
     */
    boolean checkAccountNameExist(String accountName);

}

TraineeDAOImpl

package com.nddkhang.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.nddkhang.entities.Trainee;

/**
 * The Class TraineeDAOImpl.
 */
@Component
@Transactional
public class TraineeDAOImpl implements TraineeDAO {
    @Autowired
    private SessionFactory sessionFactory;

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.nddkhang.dao.TraineeDAO#saveOrUpdateTrainee(com.nddkhang.entities.
     * Trainee)
     */
    @Override
    public final void saveTrainee(final Trainee trainee) {
        Session session = sessionFactory.getCurrentSession();
        session.save(trainee);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.nddkhang.dao.TraineeDAO#updateTrainee(com.nddkhang.entities.Trainee)
     */
    @Override
    public void updateTrainee(Trainee trainee) {
        Session session = sessionFactory.getCurrentSession();
        session.update(trainee);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.nddkhang.dao.TraineeDAO#getAllTrainees()
     */
    @SuppressWarnings("unchecked")
    @Override
    public final List<Trainee> getAllTrainees() {
        List<Trainee> list = new ArrayList<Trainee>(0);
        list = sessionFactory.getCurrentSession().createQuery("FROM " + Trainee.class.getName()).list();
        return list;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.nddkhang.dao.TraineeDAO#getTrainee(int)
     */
    @Override
    public final Trainee getTrainee(final int id) {
        Trainee trainee = new Trainee();
        trainee = (Trainee) sessionFactory.getCurrentSession().get(Trainee.class, id);
        return trainee;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.nddkhang.dao.TraineeDAO#checkEmailExist(java.lang.String)
     */
    @Override
    public final boolean checkEmailExist(final String email) {
        Query query = sessionFactory.getCurrentSession()
                .createQuery("Select t from " + Trainee.class.getName() + " t Where t.email = :key");
        query.setString("key", email);

        if (query.uniqueResult() != null) {
            return true;
        }

        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.nddkhang.dao.TraineeDAO#checkAccountNameExist(java.lang.String)
     */
    @Override
    public final boolean checkAccountNameExist(final String accountName) {
        Query query = sessionFactory.getCurrentSession()
                .createQuery("Select t from " + Trainee.class.getName() + " t Where t.accountName = :key");
        query.setString("key", accountName);

        if (query.uniqueResult() != null) {
            return true;
        }

        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.nddkhang.dao.TraineeDAO#getTraineeByEmail(java.lang.String)
     */
    @Override
    public final Trainee getTraineeByEmail(final String email) {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("From " + Trainee.class.getName() + " Where email = :key").setString("key", email);

        @SuppressWarnings("unchecked")
        List<Trainee> list = (List<Trainee>) query.list();

        return (list.isEmpty() ? null : list.get(0));
    }
}

Mong bạn nào giúp đỡ sửa lỗi này. Thanks.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?