我正在尝试编写一个Spring MVC Web应用程序,用户可以在其中将电影名称添加到内存集合中。像这样配置
public class Application extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {};
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { SpringServletConfig.class };
}
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
和
@Configuration
@ComponentScan("com.example")
public class SpringServletConfig extends WebMvcConfigurationSupport {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
}
套餐中只有一个@Controller班级com.example
@Controller
public class MovieController {
private final CopyOnWriteArrayList<Movie> movies = new CopyOnWriteArrayList<>();
@RequestMapping(path = "/movies", method = RequestMethod.GET)
public String homePage(Model model) {
model.addAttribute("movies", movies);
return "index";
}
@RequestMapping(path = "/movies", method = RequestMethod.POST)
public String upload(@ModelAttribute("movie") Movie movie, BindingResult errors) {
if (!errors.hasErrors()) {
movies.add(movie);
}
return "redirect:/movies";
}
public static class Movie {
private String filmName;
public String getFilmName() {
return filmName;
}
public void setFilmName(String filmName) {
this.filmName = filmName;
}
}
}
WEB-INF/jsps/index.jsp 包含
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Movies</title>
</head>
<body>
Current Movies:
<c:forEach items="${movies}" var="movieItem">
<ul>
<li>${movieItem.filmName}</li>
</ul>
</c:forEach>
<form:form>
<div>Movie name:</div>
<form:input path="filmName" type="text" id="name" />
<input type="submit" value="Upload">
</form:form>
</body>
</html>
该应用程序配置了上下文路径/Example。当我发送GET请求到
http://localhost:8080/Example/movies
请求失败,Spring MVC响应500状态码,并报告以下异常和堆栈跟踪
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:154)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:117)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:422)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspx_meth_form_005finput_005f0(index_jsp.java:267)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:227)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspService(index_jsp.java:142)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1257)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
我希望JSP生成
你正在尝试使用Spring MVC的form标签。
此标记呈现HTML form标记,并向内部标记公开绑定路径以进行绑定。它将命令对象放入中,PageContext
以便内部标签可以访问该命令对象。[..]
假设我们有一个名为的域对象User。这是一个JavaBean
,具有诸如firstName和的属性lastName。我们将其用作返回的表单控制器的 表单支持对象form.jsp
。
换句话说,Spring MVC
将提取命令对象并将其类型用作绑定内部标记(如或)的path表达式的蓝图,以呈现HTML 元素。forminputcheckboxform
该命令对象也称为模型属性,其名称在form标签modelAttribute
或commandName
属性中指定。你已经在JSP中省略了它
<form:form>
你可以明确指定一个名称。这两个都是等效的。
<form:form modelAttribute="some-example-name">
<form:form commandName="some-example-name">
在默认属性名称是command(你在错误信息看)。模型属性是对象,通常是POJO或POJO的集合,你的应用程序将其提供给Spring MVC堆栈,并且Spring MVC堆栈将其公开给你的视图(即MVC中的M到V)。
Spring MVC
收集所有模型属性ModelMap
(它们都有名称),对于JSP,将它们转移到HttpServletRequest
属性中,在此JSP标签和EL表达式可以访问它们。
在你的示例中,@Controller
用于处理GET路径的处理程序方法/movies添加了一个模型属性
model.addAttribute("movies", movies); // not named 'command'
然后转发到index.jsp。然后,此JSP尝试渲染
<form:form>
...
<form:input path="name" type="text" id="name" />
...
</form:form>
在呈现此代码时,FormTag(实际上是InputTag)会尝试查找名为command(默认属性名称)的模型属性,以便它可以生成一个HTML <input>
元素,该元素具有name从path表达式和相应的属性值(即)构造的属性。的结果Movie#getFilmName()
。
由于找不到它,它会引发你看到的异常
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
JSP引擎将其捕获并以500状态代码响应。如果你想利用MoviePOJO简单地正确构造表单,可以使用以下命令显式添加模型属性
model.addAttribute("movie", new Movie());
或让Spring MVC为你创建并添加一个(必须具有可访问的无参数构造函数)
@RequestMapping(path = "/movies", method = RequestMethod.GET)
public String homePage(@ModelAttribute("command") Movie movie, Model model) {...}
或者,@ModelAttribute
在你的@Controller
班级中添加带注释的方法
@ModelAttribute("command")
public Movie defaultInstance() {
Movie movie = new Movie();
movie.setFilmName("Rocky II");
return movie;
}
请注意,Spring MVC
将调用此方法,并针对由封装处理的每个请求,将返回的对象隐式添加到其模型属性中@Controller。
你可能从此描述中猜测到,Spring
的form
标签更适合<form>
从具有实际值的现有对象中呈现HTML 。如果你只想创建一个blank <form>
,那么自己构造而不依赖任何模型属性可能更合适。
<form method="post" action="${pageContext.request.contextPath}/movies">
<input name="filmName" type="text" />
<input type="submit" value="Upload" />
</form>
在接收方,你的POST处理程序方法仍将能够提取filmName输入值并将其用于初始化Movie对象。
常见错误
正如我们所看到的,FormTag
查找名为一个模型属性command
默认或名称在任一指定modelAttribute
或commandName
。确保使用正确的名称。
ModelMap有一个addAttribute(Object)增加
Map使用生成的名称为其提供的属性。
一般惯例是
返回[属性的]的小写形式的短名称Class
,根据JavaBeans
属性的命名规则:那么,com.myapp.Product
变得 product
; com.myapp.MyProduct
成为myProduct; com.myapp.UKProduct
变成UKProduct
如果你使用的是这种(或类似的)方法,或者使用的是代表模型属性的@RequestMapping 受支持的返回类型之一,请确保生成的名称符合你的期望。
另一个常见的错误是@Controller
完全绕过你的方法。典型的Spring MVC应用程序遵循以下模式:
DispatcherServlet
选择@RequestMapping
处理请求的方法DispatcherServlet
向HttpServletRequest
与视图名称相对应的JSP 添加模型属性并将其转发到JSP如果由于某种错误配置而@RequestMapping
完全跳过了该方法,则将不会添加属性。这可能发生
WEB-INF
,或welcome-list
你的中web.xm
l包含你的JSP资源,则Servlet容器将直接呈现它,从而完全绕过Spring MVC
堆栈@Controller
以一种或另一种方式调用你的模型,以便适当地添加模型属性。这BindingResult有什么关系?
A BindingResult
是用于初始化或验证模型属性的容器。在Spring MVC的文档状态
该Errors
或BindingResult
参数必须遵循被立即绑定方法签名可能有不止一个模型对象和Spring将创建一个单独的模型对象 BindingResult
为他们每个人的情况下[…]
换句话说,如果要使用BindingResult
,则必须在@RequestMapping
方法中遵循相应的model
属性参数
@RequestMapping(path = "/movies", method = RequestMethod.POST)
public String upload(@ModelAttribute("movie") Movie movie, BindingResult errors) {
BindingResult
对象也被视为模型属性。Spring MVC
使用简单的命名约定来管理它们,从而使查找对应的常规模型属性变得容易。由于BindingResult
包含有关模型属性的更多数据(例如,验证错误),FormTag
因此首先尝试绑定到该属性。但是,由于它们并存,因此没有一个就不可能存在。
问题内容: 我在网上查看了几乎所有与该问题有关的答案,但在我的代码中找不到该问题。 这是我的JSP页面。 当我删除 工作正常。我可以与控制器通信。因此问题与这条线有关。 这是我的web.xml 这是我的servlet-context.xml 还有我的applicationContext.xml 我可能在XML文件中做错了。我对于这个spring是新来的-hibernate员工,请耐心等待。谢谢..
当我只留下表显示可用的比萨饼与链接“删除”,一切显示正常,删除也正常工作。 我想表单和控制器@modelAttribute有问题,但我找不到确切的问题,我在controller中添加了与表单相同的属性--“mypiza”,这应该可以工作(至少从我在Google上找到的东西来看)。 有人能告诉我们是什么阻碍了这个应用程序的工作,以及如何解决这个问题吗?如果需要其他配置文件,我可以提供它们。
问题内容: 我在网上查看了几乎所有与该问题有关的答案,但在我的代码中找不到该问题。 这是我的JSP页面。 当我删除 它工作正常。我可以与控制器通信。因此问题与这条线有关。 这是我的web.xml 这是我的servlet-context.xml 还有我的applicationContext.xml 我可能在XML文件中做错了。我对于这个春季是新来的-休眠员工,请耐心等待。谢谢.. 这是被抛出的异常
我正在尝试使用Spring读取我在Twitter和Facebook上找到的状态,并将它们发布到SQLite数据库中。每当我尝试运行我的Spring项目时,我都会得到以下错误: 谢谢你,亚当·巴里
“bean名称'login command'的BindingResult和普通目标对象都不能作为请求属性使用” 这是我新项目的第一个控制器,我在处理xml时遇到了一些问题。我想那都解决了,但如果什么都没看到,我想问题可能就在那里。奇怪的是,所有这些代码几乎都是直接从我的另一个项目复制的,而且它工作得很好。 而且,如果这一点重要的话,我正在运行glassfish。提前道谢! 编辑:网页是/moren