在使用Spring MVC验证程序执行“浅”用户输入验证之后,是否存在一些好的做法来使用Spring MVC呈现服务层验证错误?例如,具有以下代码:

@Autowired
private UserService userService;

@RequestMapping(value = "user/new", method = RequestMethod.POST)
public String createNewUser(@ModelAttribute("userForm") UserForm userForm, BindingResult result, Model model){
    UserFormValidator validator = new UserFormValidator(); //extending org.springframework.validation.Validator
    validator.validate(userForm, result);

    if(result.hasErrors()){
        model.addAttribute("userForm", userForm);
        return "user/new";
    }

    // here, for example, the user already might exist
    userService.createUser(userForm.getName(), userForm.getPassword());

    return "redirect:user/home";
}

尽管以该代码为例似乎微不足道,但是当在服务层进行验证是一项复杂的任务时,这对我来说似乎是一个微妙的故事。尽管是一种荒谬的场景,但UserService可能会创建一个用户列表,如果其中一个已经存在,则必须以某种方式通知 View 层其中哪些无效(例如,已经存在)。

我正在寻找一种良好的做法,如何设计一段代码,这使得有可能

1)在具有复杂数据作为输入的服务层处理验证错误,并且

2)向用户展示这些验证错误

尽可能容易。有什么建议么?

最佳答案

选择通常是异常与错误代码(或响应代码),但是最佳实践(至少是Bloch的)是仅在特殊情况下使用异常,这在这种情况下不符合要求,因为用户选择现有用户名不是闻所未闻。

服务调用中的问题是您假定createUser是命令命令,没有返回值。您应该将其视为“尝试创建用户并给我结果”。那结果可能是

  • 一个整数代码(可怕的主意)
  • 来自共享结果枚举的常量(由于可维护性,还是个坏主意)
  • 是更具体的常量,例如UserOperationResult枚举(更好的主意,因为您可能会在创建新用户和尝试修改用户时都返回USER_ALREADY_EXISTS)。
  • 一个完全针对此调用定制的UserCreationResult对象(不是一个好主意,因为您会对此进行全面介绍)
  • ...期待包装器)
    未检查的异常的好处是它们避免了所有这些废话,但是它们带有自己的一系列问题。我本人会坚持最后的选择,并且过去也有不错的运气。

    关于java - 使用Spring MVC向用户呈现服务级别验证错误的一种好习惯,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21412895/

    10-11 10:30
    查看更多