Issue with Spring Form Tag in spring MVC

2.6k Views Asked by At

I am trying to build a simple application to create and update few records using spring MVC. But not able to proceed further as I am facing issue that my spring form tag has some error and I am not able to figure out since 2 days. error says:

java.lang.IllegalStateException: No WebApplicationContext found: not in a DispatcherServlet request and no ContextLoaderListener registered?

Few Doubts as well :

  1. Why do I need ContextLoaderListener when I am using dispatcherServlet.

  2. Every DispatcherServlet has its own or instantiates WebApplicationContext. Then why is the error saying its not available ?

  3. Anything that I am missing, conceptually or programmatically ?

Welcome.jsp

<html>
<body>
<h2>Welcome to the ADStore Portal</h2>
<a href="WEB-INF/views/addEmp.jsp">Add Employee</a><br>
<!-- <a href="updateEmployee.jsp">Update Employee</a> -->
</body>
</html>

addEmp.jsp

    <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <h1>Add Employee</h1>
    <form:form action = "/add" modelAttribute = "employee">
        <table>
            <tr>
                <td>Name :</td>
                <td><form:input path="empname"/>
            </tr>
            <tr>
                <td>Id :</td>
                <td><form:input path="empid"/>
            </tr>

            <tr>
                <td>Designation :</td>
                <td><form:input path="designation"/>
            </tr>

            <tr>
                <td>Department :</td>
                <td><form:input path="department"/>
            </tr>

            <tr>
                <td><input type="submit" name="Submit"/></td>
            </tr>
        </table>
    </form:form>
</body>
</html>

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">
    <display-name>AD Store</display-name>
    <servlet>
        <servlet-name>adstore</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

</web-app>

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

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

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

EmployeeController.java

    package com.adstore.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.adstore.bean.Employee;
import com.adstore.dao.EmployeeDAO;

@Controller
public class EmployeeController {
    private EmployeeDAO dao; 

    @RequestMapping(value="/add")
    public ModelAndView saveEmployee(@ModelAttribute("employee") Employee emp) {
        System.out.println("In saveEmployee");
        dao.saveEmp(emp);
        return new ModelAndView("viewEmployee","command",new Employee());
    }
}

EmployeeDAO.java

    package com.adstore.dao;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;

import com.adstore.bean.Employee;

public class EmployeeDAO {
    private JdbcTemplate jdbcTemplate;

    public boolean saveEmp(final Employee emp) {
        boolean result = false;
        String query = "INSERT INTO ADSTORE VALUES(?,?,?,?)";
        result = jdbcTemplate.execute(query, new PreparedStatementCallback<Boolean>() {

            public Boolean doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
                ps.setString(1, emp.getEmpName());
                ps.setInt(2, emp.getEmpId());
                ps.setString(3, emp.getDesignation());
                ps.setString(4, emp.getDepartment());

                return ps.execute();
            }
        });

        return result;
    }
}

Error Image::

enter image description here

3

There are 3 best solutions below

2
On

No application context is found because the request is not being handled by the DispatcherServlet as you are going directly to the JSP page. Hence there is no required Spring infrastructure to process the form:form tags.

You should access the page using the url defined in the @Controller using @RequestMapping or its variants. Its not good practice to put the JSP pages in a location which makes them accessible directly by clients. Instead you should hide them in the /WEB-INF/ directory

According to your view resolver the jsp pages should reside in the /WEB-INF/views folder. Move the JSPs to this folder.

2
On

The code which you have posted is absolutely working fine.

I don't get any exception what is posted here. But few pointers I can point it out.

  1. Check your files in the project which should be exactly same as below enter image description here
  2. You can call directly call addEmp.jsp in the starting as replacing your code.

    @RequestMapping(value = "/", method = RequestMethod.GET) public String printWelcome(@ModelAttribute("employee") Employee emp) {

    return "addEmp";
    

    }

Hope it resolves. If still you are facing issue, commit code to github and share the link.

5
On

You need to add following code in your web.xml

 <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/WEB-INF/views/*</url-pattern>
 </servlet-mapping>

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-security.xml //if you need
                /WEB-INF/adstore-servlet.xml
    </param-value>
</context-param>

and about your doubts-

1- If you want to put your Servlet file with custom name or at your custom location, rather than the default naming convention [servletname]-servlet.xml and path under Web-INF/ ,then you can use ContextLoaderListener.

Basically you can isolate your root application context and web application context using ContextLoaderListner.

The config file mapped with context param will behave as root application context configuration. And config file mapped with dispatcher servlet will behave like web application context.

In any web application we may have multiple dispatcher servlets, so multiple web application contexts.

But in any web application we may have only one root application context that is shared with all web application contexts.

We should define our common services, entities, etc in root application context. And controllers, interceptors etc are in relevant web application context.

and for more information-- The blog, "Purpose of ContextLoaderListener – Spring MVC" gives a very good explanation.