这是一个广泛的经典问题
我正在尝试编写一个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;
}
}
com中只有一个
软件包@Controller
类。示例
@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>
应用程序配置了上下文路径
/示例
。当我向
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生成一个HTML
我在一个有多个表单进行搜索的屏幕上出现了这个错误。每个表单都发布到自己的控制器方法,结果显示在同一个屏幕上。
问题:我没有在每个控制器方法中添加其他两个表单作为模型属性,导致在屏幕呈现结果时出现错误。
Form1 -> bound to Bean1 (bean1) -> Posting to /action1
Form2 -> bound to Bean2 (bean2) -> Posting to /action2
Form3 -> bound to Bean3 (bean2) -> Posting to /action3
@PostMapping
public String blah(@ModelAttribute("bean1") Bean1 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean2", new Bean2());
model.addAttribute("bean3", new Bean3());
return "screen";
}
@PostMapping
public String blahBlah(@ModelAttribute("bean2") Bean2 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean1", new Bean1());
model.addAttribute("bean3", new Bean3());
return "screen";
}
@PostMapping
public String blahBlahBlah(@ModelAttribute("bean3") Bean3 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean1", new Bean1());
model.addAttribute("bean2", new Bean2());
return "screen";
}
为了简化表单标签的使用,只需添加一个“commandName”,这是一个可怕的名称,它实际上是在寻找什么。。。它需要您在MdelAttribute注释中命名的对象。所以在本例中,commandName=“movie”。
这样你就不用读冗长的解释了,朋友。
您正在尝试使用Spring MVC的表单标记。
这个标签呈现一个HTML表单
标签,并公开一个到内部标签的绑定路径以进行绑定。它将命令对象放在PageContext
中,这样就可以通过内部标记访问命令对象。[..]
假设我们有一个名为User
的域对象。它是一个JavaBean,具有firstName
和lastName
等属性。我们将使用它作为表单控制器的表单支持对象,它返回表单。jsp
。
换句话说,Spring MVC将提取一个命令对象,并将其类型用作绑定表单
内部标记的路径
表达式的蓝图,如输入
或复选框
,以呈现HTML表单
元素。
该命令对象也称为模型属性,其名称在表单
标记的模型属性
或命令名
属性中指定。您在JSP中忽略了它
<form:form>
你可以明确地指定一个名字。这两者是等价的。
<form:form modelAttribute="some-example-name">
<form:form commandName="some-example-name">
注意:Spring 5已删除命令名称
属性,请参阅此处的升级说明。
默认属性名为命令
(您在错误消息中看到的内容)。模型属性是一个对象,通常是一个POJO或POJO集合,应用程序提供给Spring MVC堆栈,Spring MVC堆栈向您的视图公开该对象(即MVC中的M到V)。
Spring MVC收集ModelMap
中的所有模型属性(它们都有名称),并且在JSP的情况下,将它们传输到HttpServletRequest
属性,其中JSP标签和EL表达式可以访问它们。
在您的示例中,您的@Controller
处理路径/电影
的GET
的处理程序方法添加了单个模型属性
model.addAttribute("movies", movies); // not named 'command'
然后转发到索引。jsp
。然后,该JSP尝试呈现
<form:form>
...
<form:input path="name" type="text" id="name" />
...
</form:form>
在呈现该属性时,FormTag
(实际上,InputTag
)尝试查找名为command
(默认属性名称)的模型属性,以便生成HTML
因为它找不到它,所以会抛出您看到的异常
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
JSP引擎捕捉到它并用500状态代码进行响应。如果您想利用
电影
POJO来简单地正确构造表单,可以使用
model.addAttribute("movie", new Movie());
或者让Spring MVC为您创建并添加一个(必须有一个可访问的无参数构造函数)
@RequestMapping(path = "/movies", method = RequestMethod.GET)
public String homePage(@ModelAttribute("command") Movie movie, Model model) {...}
或者,在您的
@Controller
类中包含一个@Model属性
注释的方法
@ModelAttribute("command")
public Movie defaultInstance() {
Movie movie = new Movie();
movie.setFilmName("Rocky II");
return movie;
}
请注意,Spring MVC将调用此方法并为封闭的
@Controller
处理的每个请求隐式添加返回到其模型属性的对象。
从这个描述中,您可能已经猜到Spring的
表单
标记更适合呈现HTML
<form method="post" action="${pageContext.request.contextPath}/movies">
<input name="filmName" type="text" />
<input type="submit" value="Upload" />
</form>
在接收端,您的
POST
处理程序方法仍然能够提取filmName
输入值,并使用它初始化电影
对象。
如我们所见,
FormTag
在默认情况下查找名为command
的模型属性,或者使用modeldattribute
或commandName
中指定的名称。确保你用的是正确的名字。
ModelMap
有一个add属性(Object)
方法,它添加了
使用生成的名称为该
映射提供的属性。
大会将在哪里举行
<代码>com。我的应用。UKProduct变成
变成了我的产品根据JavaBeans属性命名规则:So,
<代码>com。我的应用。我的产品com,返回[attribute's]
产品类的未大写短名称。我的应用。产品
成为UKProduct
如果正在使用此(或类似)方法,或者正在使用表示模型属性的@RequestMapping
支持的返回类型之一,请确保生成的名称符合预期。
另一个常见错误是完全绕过您的@Controller
方法。典型的Spring MVC应用程序遵循这种模式:
DispatcherServlet
选择@RequestMapping
方法来处理请求DispatcherServlet
将模型属性添加到HttpServletRequest
中,并将请求转发到视图名称对应的JSP 如果由于一些错误配置,您完全跳过了@RequestMapping
方法,那么这些属性将不会被添加。这是可能发生的
WEB-INF
之外,或web.xml
的欢迎列表
包含您的JSP资源,Servlet容器将直接呈现它,完全绕过Spring MVC堆栈无论如何,您希望调用@Controller
,以便适当地添加模型属性。
BindingResult
是用于初始化或验证模型属性的容器。Spring MVC文档说明
Errors
或BindingResult
参数必须跟随立即绑定的模型对象,因为方法签名可能有多个模型对象,Spring将为每个模型对象创建一个单独的BindingResult
实例[…]
换句话说,如果你想使用BindingResult
,它必须遵循@Request estMap
方法中对应的模型属性参数
@RequestMapping(path = "/movies", method = RequestMethod.POST)
public String upload(@ModelAttribute("movie") Movie movie, BindingResult errors) {
BindingResult
对象也被视为模型属性。Spring MVC使用一个简单的命名约定来管理它们,从而很容易找到相应的常规模型属性。由于BindingResult
包含更多关于模型属性的数据(例如验证错误),FormTag
会首先尝试绑定到它。然而,由于它们是齐头并进的,不太可能有一个没有另一个就存在。
我是SpringMVC框架的初学者。两天前我开始学习Spring。出于学习目的,我正在开发一个简单的应用程序。i、 例如,从表单中获取用户输入,并在另一个页面中显示值。我得到了一个异常“java.lang.IllegalStateException:BindingResult和bean名称'command'的普通目标对象都不能作为请求属性使用”。我不知道我的代码出了什么问题。我搜索了谷歌,尝试了很
我试图在Tomcat 8.0服务器上使用Spring框架开发一个网络应用程序,但是,我被这个错误卡住了。其他两个表单页能够通过使用ModelAtinn绑定表单中的数据,然而,第三个userprofile.jsp是抛出错误“BindingResult或bean名称'setupuser'的普通目标对象都不可用作请求属性”。请帮我改掉这个错误。谢啦 错误- 可选服务控制器。爪哇- 用户配置文件。jsp
我正在努力学习SpringMVC,我面临着一个在我看来很常见的问题。我的你好。jsp是: 控制器为: 用户域名是: 代码很简单,但我面临的错误是: SEVERE: Servlet.service()对于servlet[jsp]在路径[/ChatBooster]的上下文中抛出异常[java.lang.IllegalStateExcture: BindingResult和普通目标对象的bean名称'u
嘿,我是从Spring开始的,但是我发现了这个异常并且无法解决它这是我的jsp 这是我的控制器 这是个例外
“bean名称'login command'的BindingResult和普通目标对象都不能作为请求属性使用” 这是我新项目的第一个控制器,我在处理xml时遇到了一些问题。我想那都解决了,但如果什么都没看到,我想问题可能就在那里。奇怪的是,所有这些代码几乎都是直接从我的另一个项目复制的,而且它工作得很好。 而且,如果这一点重要的话,我正在运行glassfish。提前道谢! 编辑:网页是/moren