Spring MVC CRUD控制器的最佳实践

时间:2013-07-29 15:49:11

标签: spring-mvc

我正在尝试为Spring MVC简单CRUD控制器找到最佳实践方法。在网络和论坛上有很多CRUD控制器的例子,但大多数都有两个问题之一:

  1. 保存/或更新或删除后,他们会显示保存和更新发生的消息,但他们正在点击的网址仍然包含“/ update / {id}”或“/ delete / {id}”。这是“错误的”,因为显示的内容通常是一个对象列表。
    1. 控制器重定向到“showAll”视图,但之后并不是发生动作的消息,这不是用户友好的。
    2. 有没有人有一个没有这两个问题的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;
          }
      
      }
      

1 个答案:

答案 0 :(得分:10)

  1. 您应该使用RESTful网址设计,并使用gEt到rEad,使用posT到creaTe,pUt到Update,以及Delete to Delete。对于不使用PUT或DELETE的用户代理,请使用HiddenHttpMethodFilter

  2. 使用Post-Redirect-Get模式避免重新发布。

  3. 使用Flash Attributes在后续页面上显示成功/失败消息。