我正在开发基于Spring web的项目,我遇到了将模型对象返回到要填充的JSP文件的@ModelAttribute,然后将其传递给控制器函数,然后将数据保存到数据库中。让我给你看一些代码。
这是我的软件工程课程项目,更多详细信息代码可在github上找到: https://github.com/IYTECENG316SoftwareEngineering/reddit
@Controller
public class MessageController {
@ModelAttribute("privateMessage")
public PrivateMessage constructPrivateMessage() {
return new PrivateMessage();
}
@RequestMapping(value = "/message/{id}", method = RequestMethod.POST, params = "sendMessage")
public String doSendMessage(Model model, @PathVariable("id") int id,
@Valid @ModelAttribute("privateMessage") PrivateMessage privateMessage, BindingResult result,Principal principal) {
if (result.hasErrors()) {
return showMessage(model,id);
}
User messageOwner = userService.findOne(principal.getName());
//I need to create new instance of PrivateMessage because
//(@ModelAttribute("privateMessage") PrivateMessage privateMessage) this gives always same ID.
PrivateMessage message = new PrivateMessage();
message.setMessage(privateMessage.getMessage());
message.setUser(messageOwner);
PrivateMessageConversation conversation = messageService.findOneWithMessages(id);
message.setPrivateMessageConversation(conversation);
messageService.save(message);
return "redirect:/message/"+message.getID()+".html";
}
}
PrivateMessage对象发送到jsp文件,并使用@ModelAttribute填充发送回doSendMessage函数。对象带有填充(所有输入完全写入对象)但唯一的问题是它的ID不会自动递增。还有一个我想要显示的代码。我们对主题使用相同的模板,它完美地工作。这是代码;
@Controller
public class UserController {
@ModelAttribute("topic")
public Topic contructTopic() {
return new Topic();
}
@ModelAttribute("entry")
public Entry contructEntry() {
return new Entry();
}
@RequestMapping(value = "/account", method = RequestMethod.POST)
public String doAddNewTopic(Model model,
@Valid @ModelAttribute("topic") Topic topic,
BindingResult resultTopic, Principal principal,
@Valid @ModelAttribute("entry") Entry entry,
BindingResult resultEntry,
@RequestParam("topic_category") String category_string) {
System.out.println(principal.getName() + " " + category_string + " "
+ topic.getTitle() + " " + entry.getDescription());
if (resultTopic.hasErrors()) {
return account(model, principal);
}
if (resultEntry.hasErrors()) {
return account(model, principal);
}
String name = principal.getName();
Category category = categoryService.findByName(category_string);
topic.setCategory(category);
topicService.save(topic);
entry.setTopic(topic);
entry.setPublishedDate(new LocalDateTime());
entryService.save(entry, name);
return "redirect:/topic/" + topic.getId() + ".html";
}
}
以上代码完美无缺。主题和入口对象发送到jsp,它们填充并发送回控制器,所有属性都很好,ID会自动递增。我们无法想象为什么第一个不工作。
注意:我们正在使用Hibernate,Spring Data JPA和Tiles
答案 0 :(得分:0)
在您的第一个控制器(MessageController
)中,您正在构建PrivateMessage
的新实例并保存该实例。 hibernate生成的id将在那里更改。然后,您正在使用路径模式(redirect:/message/{id}.html
)进行重定向。该模式将使用调用方法doSendMessage
的原始ID进行扩展。
在您的第二个(工作)控制器中,您没有创建Topic
的新实例,因此在保存主题后,主题中包含hibernate分配的ID。之后,您也没有使用弹簧路径扩展,而是使用新的id手动构建路径。
从
更改您的第一个控制器return "redirect:/message/{id}.html";
到
return "redirect:/message/" + message.getId() + ".html";
或
return UriComponentsBuilder.fromUriString("redirect:/message/{id}.html")
.buildAndExpand(message.getId())
.encode()
.toUriString()