我的问题可以归结为:如何让spring mvc在已经填充后调用@ModelAttribute
?
详细说明,我正在使用 Portlets in Action 中的第8章中的BookCatalog示例
由Ashish Sarin(这真的很好),我遇到了一个注释方法的问题
@ModelAttribute
仅在连续加载时才被调用一次。例如:
我已经将sysouts添加到每个方法的开头,以查看所调用的内容。结果如下:
showBooks
getBook!
initBinder
showEditBookForm
showBooks
initBinder <- Where is getBook!?
showEditBookForm
我在某处读到@ModelAttribute
只要@ModelAttribute
调用@ModelAttribute("book") Book book
方法
请求参数。所以我尝试将@ModelAttribute
添加到showEditBookForm但仍然没有触发@Controller
@RequestMapping(value="VIEW")
@SessionAttributes({"book"})
public class EditBookController {
...
@RenderMapping(params="myaction=editBookForm")
public String showEditBookForm(@ModelAttribute("book") Book book) {
System.out.println("showEditBookForm");
return "editBookForm"
}
@InitBinder("book")
public void initBinder(WebDataBinder binder) {
System.out.println("initBinder");
binder.registerCustomEditor(Long.class, new LongNumberPropertyEditor());
binder.setDisallowedFields(new String[] {"isbnNumber"});
}
@ModelAttribute("book")
public Book getBook(@RequestParam Long isbnNumber) {
System.out.println("getBook!");
return bookService.getBook(isbnNumber);
}
...
}
方法。
我正在使用Spring 3.1.3.RELEASE并使用maven部署到Liferay 6.1.1。
任何帮助都将不胜感激!
EditBookController:
@Controller
@RequestMapping(value = "VIEW")
public class BookController {
...
@RenderMapping
public String showBooks(RenderResponse response,SessionStatus sessionStatus) {
System.out.println("showBooks");
return "home";
}
...
}
BookController的:
{{1}}
答案 0 :(得分:3)
根据这行代码:
@SessionAttributes({"book"})
public class EditBookController {
您正在使用“book”属性作为会话属性。这意味着第一次向Portal发出请求时,框架将验证Portlet会话中是否存在具有该名称的属性。如果不是,它将调用相应的@ModelAttribute
方法生成实例并将其放入Session。但是如果Session中已经存在具有该名称的属性,则Controller将使用现有对象。
因此,当您第一次调用Book Catalog Portlet时,会生成Book属性的一个实例并将其存储在Session中。但第二次 - 如果一个对象已经在Session中 - Portlet将使用第一个请求中生成的对象。如果要在渲染或操作请求后清除存储在Session中的每个对象,只需调用SessionStatus.setComplete()
即可触发会话清理。
这就是理论和书中所说的,但SessionStatus.setComplete()
和Book Author has some thoghts about it中存在一些错误的行为。
答案 1 :(得分:0)
只是为了说明我最终的目标:
@RenderMapping(params="myaction=editBookForm")
public String showEditBookForm(
@ModelAttribute("book") Book book
, @RequestParam Long isbnNumber
, SessionStatus sessionStatus) {
System.out.println("showEditBookForm");
if(book != null
&& book.getIsbnNumber() != isbnNumber) {
sessionStatus.setComplete();
}
return "editBookForm";
}