5

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

  1. 保存/更新或删除后,它们会显示保存和更新发生的消息,但他们点击的 URL 上仍然有“/update/{id}”或“/delete/{id}”。这是“错误的”,因为显示的内容通常是对象列表。

或者

  1. 控制器重定向到“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;
    }

}
4

1 回答 1

10
  1. 您应该使用RESTful URL 设计,并使用 get 来阅读,使用 post 来创建,使用 pUt 来更新,使用删除来删除。对不 PUT 或 DELETE 的用户代理使用HiddenHttpMethodFilter 。

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

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

于 2013-07-29T18:35:02.400 回答