【问题标题】:Spring annotation relation with <form:form commandName="xy" [duplicate]与 <form:form commandName="xy" 的 Spring 注释关系 [重复]
【发布时间】:2011-11-13 11:24:56
【问题描述】:

我是 Spring 注释和 MVC 的新手。我的第一页是 home.jsp,现在它没有出现在 Tomcat 服务器中,我在控制台中看到了最后显示的错误。 我试图创建一个非常简单的注释应用程序。这里是控制器。

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller

    //@RequestMapping()
    public class UserLoginController {

    public UserLoginController(){

    }
        //@RequestMapping(value="/get" , method = RequestMethod.GET)
    //@ModelAttribute("user")
        public String get(final ModelMap model) {

            User userForm = new User();
      model.addAttribute("userLogin", userForm);
       return "form";
        }

        @RequestMapping(value="/home.jsp", method = RequestMethod.POST)
        public String post(Model model) {

           String test=" inside here";

            return "success";
        }
    }

这是 JSP

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page session="false" %>
<%@ include file="/WEB-INF/views/header.jsp" %>

 <html>
<head>
<meta http-equiv="Content-Type" content="text/html">
<title>iBank - Home-version 2.0</title>
</head>
<body>
<h1 align="center">Welcome to iBank-Dhiren</h1>
<h2 align="center">Your Online Bank Portal</h2>
<p align="center">   
Today is ${today}.<br/>
<a href="<%=request.getContextPath()%>/admin.htm">Modified Administration Site-version-1.0 </a>
</p>
</body>
</html>

<p>
    <form:form  method="post" commandName="user">
        <div>
            <form:label path="name">Name:</form:label>
            <form:input path="name"/>
            <form:errors path="name" />
        </div>
        <div>
            <form:label path="email">Email:</form:label>
            <form:input path="email" />
            <form:errors path="email" />
        </div>
        <div>
            <input type="submit" value="  OK  "/>
        </div>
    </form:form>
</p>

</html>

既然 JSP 应该进入 UserLoginController,那么它是如何提交的。我看不到注释值之间的任何连接,而且我的 Tomcat 服务器也出现此错误。

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' 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:174)

谢谢 迪伦


好的,我无法再进一步了。我尝试了所有,但仍然完全卡住了。

我的 JSP 主页.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page session="false" %>
<%@ include file="/WEB-INF/views/header.jsp" %>

 <html>
<head>
<meta http-equiv="Content-Type" content="text/html">
<title>iBank - Home-version 2.0</title>
</head>
<body>
<h1 align="center">Welcome to iBank-Dhiren</h1>
<h2 align="center">Your Online Bank Portal</h2>
<p align="center">   
Today is ${today}.<br/>
<a href="<%=request.getContextPath()%>/admin.htm">Modified Administration Site-version-1.0 </a>
</p>
</body>
</html>

<p>
    <form:form  method="post" action="/user.jsp" modelAttribute="user">

        <div>
            <form:label path="firstName">Name:</form:label>
            <form:input path="firstName"/>
            <form:errors path="firstName" />
        </div>
        <div>
            <form:label path="password">Password:</form:label>
            <form:input path="password" />
            <form:errors path="password" />
        </div>
        <div>
            <form:label path="middleName">Middle name:</form:label>
            <form:input path="middleName" />
            <form:errors path="middleName" />
        </div>
        <div>
            <form:label path="lastName">LastName:</form:label>
            <form:input path="lastName" />
            <form:errors path="lastName" />
        </div>


        <div>
            <input type="submit" value="  OK  "/>
        </div>
    </form:form>
</p>

</html>

我的用户登录控制器

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller

    //@RequestMapping()
    public class UserLoginController {

    public UserLoginController(){

    }
        //@RequestMapping(value="/get" , method = RequestMethod.GET)
    //@ModelAttribute("user")
        public String get(final ModelMap model) {

            User userForm = new User();
      model.addAttribute("userLogin", userForm);
       return "form";
        }

        @RequestMapping(value="/user.jsp", method = RequestMethod.POST)
        public String post(final User user, final BindingResult result, Model mv) {

           String test=" inside here";

            return "success";
        }
    }

用户类

import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

public class User {
/*  @NotEmpty
    @Size(max = 20)
    */
private String userId;
    /*@NotEmpty
    @Size(max = 20)
*/
private String password;
private String firstName;
private String middleName;
private String lastName;
//private int userAccessLevel;
/**
 * @return the userId
 */
public String getUserId() {
    return userId;
}
/**
 * @param userId the userId to set
 */
public void setUserId(String userId) {
    this.userId = userId;
}
/**
 * @return the password
 */
public String getPassword() {
    return password;
}
/**
 * @param password the password to set
 */
public void setPassword(String password) {
    this.password = password;
}
/**
 * @return the firstName
 */
public String getFirstName() {
    return firstName;
}
/**
 * @param firstName the firstName to set
 */
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
/**
 * @return the middleName
 */
public String getMiddleName() {
    return middleName;
}
/**
 * @param middleName the middleName to set
 */
public void setMiddleName(String middleName) {
    this.middleName = middleName;
}
/**
 * @return the lastName
 */
public String getLastName() {
    return lastName;
}
/**
 * @param lastName the lastName to set
 */
public void setLastName(String lastName) {
    this.lastName = lastName;
}
/**
 * @return the userAccessLevel
 *
public int getUserAccessLevel() {
    return userAccessLevel;
}
*/
/**
 * @param userAccessLevel the userAccessLevel to set
 *
public void setUserAccessLevel(int userAccessLevel) {
    this.userAccessLevel = userAccessLevel;
}*/

}

这些是 context.xml 文件 servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-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">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

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

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

        <!-- Imports user-defined @Controller beans that process client requests -->

    <context:component-scan base-package="mytest.apps" />

</beans:beans>

谁能告诉我为什么 home.jsp 没有出现

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>appServlet</display-name>
    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>  
  <param-name>log4jConfigLocation</param-name>  
  <param-value>/WEB-INF/log4j.xml</param-value>  
</context-param>  
<listener>  
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
</listener> 

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/root-context.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/appServlet/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>

当我尝试访问 Web 应用程序的第一页时出现所有这些错误,我在 Tomcat 中收到此错误。

INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned where no TLDs were found. Skipping JAR scanning can improve startup time and JSP compilation time.
log4j:ERROR Attempted to append to closed appender named [console].
Sep 14, 2011 10:02:39 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' 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:174)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
    at org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:129)
    at org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:119)
    at org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:89)
    at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
.
.
Sep 14, 2011 10:02:39 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/AdministrativeApplication] threw exception [An exception occurred processing JSP page /WEB-INF/views/home.jsp at line 25

22:     <form:form  method="post" action="/user.jsp" modelAttribute="user">
23:      
24:         <div>
25:             <form:label path="firstName">Name:</form:label>
26:             <form:input path="firstName"/>
27:             <form:errors path="firstName" />
28:         </div>


Stacktrace:] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)

请帮忙

谢谢 迪伦

【问题讨论】:

  • 在 jsp 中使用 scriptlet 标签 通常被视为不好的做法。它们仅包含视图逻辑,并且很容易滥用它们的功能。我建议完全避免使用它们,而是将值设置为请求属性并使用 ${} 标签来显示它们。

标签: spring-mvc


【解决方案1】:

“commandName”用于绑定模型和表单中的数据。 如果你有类(模型)定义如下:

public class UserQuery {

    public String message;

    public String getMessage()
    {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    } 
}

JSP 文件(数据):

<prefix:form method="POST" commandName="UserQuery">
  <sf:input path="message" /><br/>
  <input type="submit"/>
</prefix:form>

还有 GET/POST 控制器:

@Controller
public class ContactController {

    @RequestMapping(value="/Contact",method=RequestMethod.GET)
    ModelAndView Contact(Model model)
    {
        model.addAttribute("UserQuery",new Query());

        return new ModelAndView("contactView");
    }

    @RequestMapping(value="/Contact",method=RequestMethod.POST)
    ModelAndView Contact()
    {
        //Here you can get you're attribute and render it
        // in other view 
        return new ModelAndView("contactFormFiledView");
    }
}

GET 方法 -> 用于创建属性“UserQuery”并将其与模型“Query”绑定,这是您的类。通过绑定我的意思是:如果用户单击表单中的提交按钮,则表单中的数据将传递给属性在“commandName”中指定。

【讨论】:

  • 我真的认为 model.addAttribute("UserQuery", ...) , commandName="UserQuery"> 和公共类 UserQuery 都必须匹配。
【解决方案2】:

解决您的第一个问题。 将 home.jsp 保存在 webapp 部分内的资源文件夹下。 对 servlet-xml 文件进行适当的更改,如下所示。

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

在控制器中添加一个方法来处理对主页的请求。

@RequestMapping(value = "/home", method = RequestMethod.GET) 
public String displayLogin(Model model) { 
    model.addAttribute("login", new Login()); 
    System.out.println("Returning index page");
    return "index"; 
}

您的新网址将类似于 http://localhost:8080/ProjectName/home

确保在上面提到的 displayLogin 方法中添加model.addAttribute("login", new Login());

这应该会有所帮助。
问候
BinoyC

【讨论】:

    【解决方案3】:

    在你的get方法中,添加命令对象

    public String get(final ModelMap model) {
    
      User userForm = new User();
      model.addAttribute("command", userForm);
      return "form";
    }
    

    【讨论】:

      【解决方案4】:

      这很简单…………

      model.addAttribute("**user**",userForm );
      

      这意味着,您的命令名称应该与模型属性名称完全相同... 因此,如果您的 jsp 文件中的命令名称是“user”,那么您的模型应该添加名称为“user”的属性。

      【讨论】:

        【解决方案5】:
        model.addAttribute("**userLogin**", userForm); // in controller
        return "form"; //in controller
        

        在 JSP 中你应该给

        form:form  method="post" action="/user.jsp" modelAttribute="userLogin"
        

        (而不是modelAttribute/commandName="user"

        试试这个你不会得到

        java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute" expection.
        

        【讨论】:

          【解决方案6】:
          class User() {
              String name;
              String email;
          
              //bean getters and setters
          }
          
          public String post(Model model, User user) {
             ....
          }
          

          我几天前才开始使用弹簧绑定。

          您设置它的方式我相信您的表单会尝试创建一个具有“电子邮件”和“名称”属性的“用户”对象。

          编辑

          我想我理解这个问题......

          <form:form  method="post" commandName="user">
          

          这告诉 spring 你想用来自用户对象的数据预填充表单。如果这是您想要做的,那么您需要为 jsp 提供一个名为“user”的请求属性。

          如果您尝试使用表单提交数据,我认为是这种情况,我认为您想改用它

          <form:form  method="post" modelAttribute="user">
          

          【讨论】:

          • 那我什至不能显示要显示此表单的第一页吗?谢谢
          • 哦,您是在尝试用数据预填充表单,还是使用表单来提交数据?
          • 不,我不会重新填充,至少这还不是刚开始的意图。我想要一个空的登录类型的 loginId 输入页面显示提交。我无法显示该页面。
          • 您看到我对答案所做的修改了吗?
          • 是的,我看到了您的编辑。感谢cmets。我有个问题。当我发帖时,spring 如何知道需要调用哪个控制器。当我发布帖子时,spring 如何绑定要调用的 UserLoginController 。我的 RequestMapping 到底应该是什么样的。谢谢
          【解决方案7】:

          您的post() 方法应将命令对象作为其参数之一:

          public String post(final User user, final BindingResult result) {
          

          在这种情况下发布数据后,表单中的字段nameemail将分别绑定到user.nameuser.email

          【讨论】:

          • 我什至无法获得第一部分,即要显示的表单。这会导致问题吗?
          • 我到底做错了什么。这是我修改后的代码。
          • @djoshi 为什么你注释掉了@RequestMappingget() 方法?你绑定DispatcherServlet 到什么url-pattern?让我们从头开始:您应该打开页面/get 并查看表格。提交后,您应该在/home.jsp 页面。您在哪里遇到了什么错误?
          • 我无法访问我的起始页 home.jsp。注释了 get 是因为我使用此方法调用也不起作用的操作。 @RequestMapping(value="/home.jsp", method = RequestMethod.POST) public String post(Model model) { String test=" inside here";返回“成功”; }
          • @djoshi 您无法获得/home.jsp,因为您通过GET 方法请求它,但只为POST 方法定义处理程序。我建议取消注释 get() 方法并调用它来显示表单。
          猜你喜欢
          • 2013-04-15
          • 2014-10-10
          • 1970-01-01
          • 2011-11-24
          • 2018-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-04
          相关资源
          最近更新 更多