2016-11-29 253 views
2

我在Spring中构建了一个REST api,并且在处理异常时遇到了问题。我想验证完整请求并一次性提供有关有效负载的信息。Spring jackson反序列化和异常处理

假设我的目标是

public class StubJson { 
    private BigDecimal bigDecimalField; 
    @NotEmpty 
    private String stringField; 

    public void setBigDecimalField(BigDecimal bigDecimalField) { this.bigDecimalField = bigDecimalField; } 
    public String setStringField(String stringField) { this.stringField = stringField; } 
} 

我的控制器是

@RestController 
public class StubController { 
    @RequestMapping(value = "/stub", method = POST) 
    public void stub(@Valid @RequestBody StubJson stubJson) {} 
} 

这个对象上的验证是在转变FieldError对象到最终用户转换误差的@ControllerAdvice。

@ResponseStatus(BAD_REQUEST) 
@ResponseBody 
@ExceptionHandler(value = MethodArgumentNotValidException.class) 
public List<ErrorJson> processValidationError(MethodArgumentNotValidException ex) {} 

如果我通过在此JSON

{"bigDecimalField": "text", "stringField": ""} 

我想这样

[ 
    { 
    "field": "stringField", 
    "message": "Cannot be empty." 
    }, 
    { 
    "field": "bigDecimalField", 
    "message": "Not a number." 
    } 
] 

的响应。如果我这样做,我得到一个

com.fasterxml。 jackson.databind.exc.InvalidFormatException

上BigDecimalField其中只包含有关只有一个字段的信息。我看到的唯一选择是将其作为字符串传递或编写自定义验证注释。有没有更简单的方法来实现这一点?

+0

即使在准备好验证之前,对象转换仍然失败。为了实现你想要的东西,需要你的对象需要从你的json请求中成功创建 – ScanQR

回答

0

您可以为此使用控制器建议。在你的应用程序中声明一个控制器建议,捕获你期望的异常,转换为你需要的响应并返回。请记住,控制器建议将应用于您的所有控制器。

@ControllerAdvice 
public class ExceptionHandlerController { 

@ExceptionHandler(InvalidFormatException.class) 
    @ResponseBody public String typeMismatchException(HttpServletRequest request, HttpServletResponse servletResponse, InvalidFormatException e) { 

     String yourResponse = ""; 
     return yourResponse; 
    } 

} 
+0

我目前的实现使用@ControllerAdvice来捕获包含多个字段验证错误的MethodArgumentNotValidException,而InvalidFormatException只包含关于一个字段的信息。我会更新我的问题以使其更清楚。 – jgeerts