如何从Spring MVC控制器返回错误状态和验证错误?

K E*_*est 8 java spring spring-mvc

我在我的一个控制器中有一个这样定义的动作方法:

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Post create(@Valid Post post, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        // how to return an error status + error messages from here?
    } else {
        postRepository.persist(post);
        return post;
    }
}
Run Code Online (Sandbox Code Playgroud)

当帖子成功保留后,我将帖子返回给客户端.但是当它有验证错误时,我想将错误状态代码以及所有验证错误消息返回给客户端.

最好的方法是什么?

Łuk*_*man 7

正如您所设计的那样,您需要创建自己的Pojo(aka.资源),这将代表奇怪的行为或验证错误,正如horaceman所述.我将在我们的应用程序中向您展示我们是如何做到的.

由于我们使用JSON作为数据表示,因此如果发生意外异常,我们希望收到以下信息.

{ "status" : "EXCEPTION", "exceptionName" : "MyCustomException", "exceptionMsg" : "ex.unsupportedOperation" }
Run Code Online (Sandbox Code Playgroud)

这是一个例子.关于它的一个很好的解决方案是我们可以将exceptionMsg我们的前端中的一个键视为显示正确的i18n消息或将其显示给用户(在这种情况下,我们使用更多的描述性消息).

现在,当一切正常时,我们会这样做:

{ "status" : "OK", "data" : {(...)} }
Run Code Online (Sandbox Code Playgroud)

Data元素是可选的.我们可以发送任何我们需要通知前端的内容,或完全跳过它.

最后一个场景是你的 - 验证错误.在这种情况下,我们通常发送以下内容:

{ "status" : "VALIDATION_FAILED", "errors" : [ "fieldName" : "username", "errorCode" : "validation.requiredField", "errorMsg" : "Username is required."] }
Run Code Online (Sandbox Code Playgroud)

很明显,API客户端将收到验证失败的信息,并在适当的字段中显示错误的详细信息.当然errors是一个数组(或List),所以我们总是根据需要提供尽可能多的细节.

我是怎么做到的 很简单,那些对象是简单的POJOS,使用Jackson翻译成JSON.这给了我无限的JSON表示可能性.我做的是,我正在准备代表验证错误的POJO(例如)并将其添加为Model我的ModelAndView实例.然后我只依靠Spring来做适当的JSON编组.

在你的情况下,你有@ResponseBody你的Post实例的注释,所以据我所知你将无法做到这一点.你的设置是说"好吧,不管发生了什么 - 总是返回一个Post的实例".你应该做的是用简单的替换它,根据验证ModelAndView提供适当Model的,并将其返回到客户端API.


Ros*_*hev 5

对于@ResponseBody,我将从方法签名中删除 BindigResult 并让 BindException 被抛出。然后,我将使用 @ExceptionHandler 方法返回一个包含 Likacz 描述的错误的对象。

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Post create(@Valid Post post) {
    postRepository.persist(post);
    return post;
}

@ExceptionHandler
public ValidationErrors handleException(BindException ex) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您想在响应正文中返回 `ValidationErrors`,`handleException` 方法将需要 `@ResponseBody`。 (2认同)