这是一篇关于这类问题的广泛的规范问答文章。
我正在尝试编写一个springmvcweb应用程序,用户可以在其中向内存中的集合添加电影名称。是这样配置的
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"%>
5条答案
按热度按时间eqqqjvef1#
在我的例子中,它通过添加
modelAttribute="movie"
并在属性前面加上模型名,类似于<form:input path="filmName" type="text" id="movie.name" />
hs1ihplo2#
从springversion3更新到springversion5会产生相同的错误。我的代码中已经给出了所有的答案。添加注解
@ControllerAdvice
帮我解决了这个问题。r6hnlfcb3#
为了简化form标签的使用,只需添加一个“commandname”,这是一个可怕的名称,它实际上是在寻找什么…它想要你在mdelattribute注解中命名的对象。所以在本例中commandname=“movie”。
这样你就不用读冗长的解释了,朋友。
368yc8dk4#
我在一个有多个表单进行搜索的屏幕上遇到了这个错误。每个窗体都将结果发布到自己的控制器方法,结果显示在同一屏幕上。
问题:我没有在每个控制器方法中添加另外两个窗体作为模型属性,这导致在屏幕呈现结果时出现错误。
n1bvdmb65#
您正在尝试使用SpringMVC的表单标记。
此标记呈现html
form
标记并向内部标记公开绑定路径以进行绑定。它将命令对象放入PageContext
以便内部标记可以访问命令对象。[..]假设我们有一个名为
User
. 它是一个具有如下属性的javabeanfirstName
以及lastName
. 我们将使用它作为返回form.jsp
.换句话说,springmvc将提取一个command对象,并将其类型用作绑定的蓝图
path
的表达式form
的内部标记,如input
或者checkbox
,以呈现htmlform
元素。此命令对象也称为模型属性,其名称在
form
标签modelAttribute
或者commandName
属性。您在jsp中省略了它你可以明确指定一个名字。这两者是等价的。
默认属性名为
command
(您在错误消息中看到的内容)。模型属性是一个对象,通常是一个pojo或pojo的集合,应用程序将其提供给springmvc堆栈,springmvc堆栈将其公开给您的视图(即mvc中的m到v)。springmvc在一个数据库中收集所有模型属性
ModelMap
(它们都有名字)并且,在jsp的情况下,将它们转移到HttpServletRequest
属性,其中jsp标记和el表达式可以访问它们。在你的例子中,你的
@Controller
处理GET
通往小路/movies
添加单个模型属性然后转到
index.jsp
. 然后,这个jsp尝试呈现渲染时,
FormTag
(实际上InputTag
)尝试查找名为command
(默认属性名),以便它可以生成html<input>
带有name
由path
表达式和相应的属性值,即Movie#getFilmName()
.因为它找不到它,所以抛出您看到的异常
jsp引擎捕捉到它并用500状态码响应。如果你想利用
Movie
为了简单地正确构造表单,可以使用或者让springmvc为您创建并添加一个(必须有一个可访问的无参数构造函数)
或者,包括
@ModelAttribute
在您的@Controller
班请注意,springmvc将调用此方法,并隐式地将返回的对象添加到由封闭
@Controller
.你可能已经从这个描述中猜到了Spring
form
标记更适合呈现html<form>
从现有对象中,使用实际值。如果您只想创建一个空白<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应用程序遵循以下模式:发送http get请求
DispatcherServlet
选择@RequestMapping
处理请求的方法handler方法生成一些模型属性并返回视图名称
DispatcherServlet
将模型属性添加到HttpServletRequest
并将请求转发到视图名称对应的jspjsp呈现响应
如果由于某些配置错误,您跳过了
@RequestMapping
方法,则不会添加属性。这是可能发生的如果您的http请求uri直接访问您的jsp资源,例如,因为它们是可访问的,即在外部
WEB-INF
,或如果
welcome-list
你的web.xml
包含您的jsp资源,servlet容器将直接呈现它,完全绕过springmvc堆栈不管怎样,你都想
@Controller
以便适当地添加模型属性。这和bindingresult有什么关系?
一
BindingResult
是用于初始化或验证模型属性的容器。springmvc文档说明这个
Errors
或者BindingResult
参数必须跟随立即绑定的模型对象,因为方法签名可能有多个模型对象,spring将创建一个单独的BindingResult
每个示例[…]换句话说,如果你想用
BindingResult
,它必须遵循@RequestMapping
方法