Spring MVC CRUD控制器最佳实践
问题内容:
我正在尝试为Spring MVC简单CRUD控制器找到最佳实践方法。Web和此论坛上都有很多CRUD控制器示例,但其中大多数都存在以下两个问题之一:
- 保存/或更新或删除后,它们会显示已发生保存和更新的消息,但所命中的URL上仍带有“ / update / {id}”或“ / delete / {id}”。这是“错误的”,因为显示的内容通常是对象列表。
要么
- 控制器将重定向到“ showAll”视图,但是随后没有消息表明已执行操作,这不是用户友好的操作。
有没有人举过一个没有这两个问题的crud控制器示例?
谢谢,
亨利
@Controller
@RequestMapping(value="/role")
public class RoleController {
private static final Logger log = Logger.getLogger(RoleController.class);
@Autowired
private RoleValidator validator = null;
@Autowired
private RoleService service = null;
public void setService(RoleService service) {
this.service = service;
}
public void setValidator(RoleValidator validator) {
this.validator = validator;
}
@RequestMapping(method=RequestMethod.GET)
public String showForm(ModelMap model){
List<Role> domainObjectList = service.getRoles();
model.addAttribute("domainObjectList", domainObjectList);
return "role";
}
@RequestMapping(value="/add", method=RequestMethod.GET)
public String preAdd(ModelMap model){
Role domainObject = new Role();
model.addAttribute("domainObject", domainObject);
addConstrainedFields(model);
return "roleEdit";
}
@RequestMapping(value="/add", method=RequestMethod.POST)
public ModelAndView add(@ModelAttribute(value="domainObject") Role domainObject, BindingResult result) {
validator.validate(domainObject, result);
ModelAndView mv = new ModelAndView("role");
if(result.hasErrors()){
mv = new ModelAndView("roleEdit");
mv.addObject("domainObject", domainObject);
return mv;
}
service.insertRole( domainObject );
mv.addObject("domainObjectList", service.getRoles());
mv.addObject("messageKey","label.form.item.added");
//PROBLEM: the URL will remain "/add", but the content will be one of showing all roles + message that role was added.
return mv;
}
@RequestMapping(value="/update/{id}")
public String preUpdate(@PathVariable Integer id, ModelMap model) {
Role domainObject = service.getRole( id );
model.addAttribute("domainObject", domainObject);
return "roleEdit";
}
@RequestMapping(value="/update", method=RequestMethod.POST)
public String update(@ModelAttribute(value="domainObject") Role domainObject, ModelMap model, BindingResult result){
validator.validate(domainObject, result);
ModelAndView mv = new ModelAndView("role");
if(result.hasErrors()){
model.addAttribute("domainObject", domainObject);
return "roleEdit";
}
service.insertRole(domainObject);
model.addAttribute("messageKey","label.form.item.added");
model.addAttribute("domainObjectList", service.getRoles());
//PROBLEM: the message that the object was updated will be lost, but the URL will be /role and we will show all roles.
return "redirect:/role";
}
@RequestMapping(value="/delete/{id}")
public String delete(@PathVariable Integer id, ModelMap model) {
Role domainObject = service.getRole( id );
if (domainObject == null) {
model.addAttribute("messageKey","label.form.item.notfound");
return showForm(model);
}
service.deleteRole(domainObject);
model.addAttribute("messageKey","label.form.item.deleted");
return showForm(model);
}
@RequestMapping(value="/delete", method=RequestMethod.POST)
public ModelAndView delete(@ModelAttribute(value="domainObject") Role domainObject, BindingResult result){
validator.validate(domainObject, result);
ModelAndView mv = new ModelAndView("role");
if(!result.hasErrors()){
service.deleteRole(domainObject);
mv.addObject("messageKey","label.form.item.deleted");
domainObject = new Role();
mv.addObject("domainObject", domainObject);
}
mv.addObject("domainObjectList", service.getRoles());
return mv;
}
}
问题答案:
-
您应该使用RESTful URL设计,并使用gEt进行排序,使用posT进行创建,使用PUt进行更新,以及使用Delete to Delete。将HiddenHttpMethodFilter用于没有PUT或DELETE的用户代理。
-
使用Post-Redirect-Get模式可以避免重新发布。
-
使用Flash属性在后续页面上显示成功/失败消息。