如何解决“ java.lang.IllegalStateException:BeanResult'customer'的BindingResult或普通目标对象都不能用作请求属性”?


问题内容

我正在尝试将Spring Validation与批注一起使用,并且不断遇到相同的异常:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customer' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198)
at org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:129)
at org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:119)
Truncated. see log file for complete stacktrace

我看了几本教程,并仔细检查了我能想到的所有内容。我不确定我的问题在哪里。网页加载时都会发生该异常。任何帮助,将不胜感激。

弹簧-mvc-servlet.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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd   http://www.springframework.org/schema/jee  http://www.springframework.org/schema/jee/spring-jee-3.0.xsd   http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">


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


    <mvc:annotation-driven/>


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property value="/" name="prefix"></property>
    </bean>
</beans>

addCustomer.jsp

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ 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>Add Customer</title>

</head>
<body>
<form:form action="addCustForm"  method="POST" commandName="customer" modelAttribute="customer">
    <table border="2">
        <tr><td><form:label path="fname">Customer First Name: </form:label></td><td><form:input path="fname" id="fname"/><form:errors path="fname" cssClass="error"/> </td></tr>
        <tr><td><form:label path="lname">Customer Last Name: </form:label></td><td><form:input path="lname" id="lname"/><form:errors path="lname" cssClass="error"/> </td></tr>
        <tr><td><form:label path="phone">Customer Phone Number: </form:label></td><td><form:input path="phone" id="phone"/><form:errors path="phone" cssClass="error"/> </td></tr>
        <tr><td><form:label path="address">Customer Address: </form:label></td><td><form:input path="address" id="address"/><form:errors path="address" cssClass="error"/> </td></tr>
        <tr><td><form:label path="email">Customer E-Mail: </form:label></td><td><form:input path="email" id="email"/><form:errors path="email" cssClass="error"/> </td></tr>
    </table>
    <input type="submit" value="Submit Customer Info"/>
</form:form>
</body>
</html>

AddCustomerController.java

package controllers;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import dao.Customer;

@Controller
@RequestMapping("/addCustForm")
public class AddCustomerController {



    @RequestMapping(method=RequestMethod.POST)
    public String addCustomer(@Valid Customer customer, BindingResult result, ModelMap map, HttpServletRequest request) throws Exception{
        if(result.hasErrors()){
            return "addCustomer.jsp";
        }

        map.addAttribute("message",customer.getFname());
        return "Menu.jsp";
    }
}

客户.java

package dao;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.ws.BindingType;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.stereotype.Component;

@Component
@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    int custid;
    @Column
    @NotEmpty/*(message="First Name Is Required")*/
    /*@Pattern(regexp="{a-zA-Z}", message="First Name must be all letters")*/
    String fname;
    @NotEmpty/*(message="Last Name Is Required")*/
    /*@Pattern(regexp="{a-zA-Z}", message="Last Name must be all letters")*/
    String lname;
    @NotEmpty/*(message="Address Is Required")*/
    /*@Pattern(regexp="{a-zA-Z0-9}", message="Address must be contain only letters and numbers")*/
    String address;
    @NotEmpty/*(message="Email is Required")*/
    /*@Email(message="Invalid Email Address")*/
    String email;
    @NotEmpty/*(message="Phone Number is Required")*/
    /*@Size(min=10,max=10)
    @Pattern(regexp="{0-9}", message="Phone Number must be all Numbers(no '- or ()'")*/
    String phone;

//Getters and Setters

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>Inventory-Management-System</display-name>

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

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-mvc-servlet.xml</param-value>
  </context-param>

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

  <servlet>
    <servlet-name >spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

   <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
   </servlet-mapping>



</web-app>

问题答案:

从您的评论看来,您似乎正在将初始请求发送到

localhost:7001/InventoryManagementProject/addCustomer.jsp

我将假设这意味着所讨论的JSP是生成的WAR的根源。因此,您无需通过Spring即可直接访问它@Controller但是,这就是问题所在。

您的JSP包含

 <form:form action="addCustForm"  method="POST" commandName="customer" modelAttribute="customer">

<form:form>是Spring
form标记库中的标记。处理完该请求后,它将查找名为commandName或在中指定的名称的请求属性modelAttribute(请注意,指定两者都是多余的,请仅使用其中之一)。在这种情况下,它将查找名为的请求属性customer,但是由于您尚未设置此类请求属性,因此处理此标记将失败。

一种解决方案是让您的请求@Controller在呈现JSP之前经过处理程序方法。首先,将你的JSP内WEB- INF并解决您InternalResourceViewResolver有一个适当的prefixsuffix。然后添加一个像

@RequestMapping(value = "/add-customer", method = RequestMethod.GET)
public String getAddCustomerForm(Model model) {
    model.addAttribute("customer", new Customer());
    return "addCustomer";
}

这样做是Customer在模型属性中添加一个新对象(最终被添加为请求属性),以便在创建表单时将其用作模板。