春季验证器未向客户端提供消息

huangapple go评论116阅读模式
英文:

Spring Validator Not Providing Message to Client

问题

我目前正在开发一个Spring RESTful服务,并且正在使用验证注解来确保请求体对象中的参数存在。然而,由于某种原因,Spring验证似乎默认情况下不会向客户端用户提供有关其请求无效的任何信息。

数据对象类:

....
    @Min(10000000000L)
    @Max(19999999999L)
    private long id;
    
    private boolean restricted;
....

控制器:

@PostMapping("/userRestriction")
    public ResponseEntity<String> userRestriction(
            @Valid @RequestBody(required = true) User user) {

请求:

{
    "id":"A",
    "restricted":false
}

结果:

{
    "timestamp": "2020-07-23T14:20:57.273+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "",
    "path": "/userRestriction"
}

日志:

2020-07-23 09:20:57.271  WARN 28035 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : 解析 [org.springframework.http.converter.HttpMessageNotReadableException: JSON解析错误: 无法从字符串"A"反序列化为类型 `long`: 不是有效的Long值; 嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException: 无法从字符串"A"反序列化为类型 `long`: 不是有效的Long值
 at [Source: (PushbackInputStream); line: 2, column: 11] (through reference chain: myPackage.dataObjects.User["id"])]

我希望Spring能够至少在错误消息中提供异常信息,以便在进行最小可行性产品迭代时能够解决问题。这样,尽管可能有点难以理解,但客户端最终仍然可以理解他们做错了什么,然后我可以稍后添加自定义错误处理,但似乎情况并非如此?

如果不行的话,我需要在错误/异常处理器类中实现哪些方法来正确处理验证器错误?

谢谢

英文:

I'm currently developing a Spring RESTful service and am using the validation annotation to ensure parameters within the object of the body of the request are present. However, for some reason the Spring validation does not appear to, by default, provide the client user with ANY information on why their request could have been invalid

Data Object class:

....
    @Min(10000000000L)
    @Max(19999999999L)
    private long id;
    
    private boolean restricted;
.....

Controller:

@PostMapping(&quot;/userRestriction&quot;)
    public ResponseEntity&lt;String&gt; userRestriction(
            @Valid @RequestBody(required = true) User user) {

Post:

{
	&quot;id&quot;:&quot;A&quot;,
	&quot;restricted&quot;:false
}

Result:

{
    &quot;timestamp&quot;: &quot;2020-07-23T14:20:57.273+00:00&quot;,
    &quot;status&quot;: 400,
    &quot;error&quot;: &quot;Bad Request&quot;,
    &quot;message&quot;: &quot;&quot;,
    &quot;path&quot;: &quot;/userRestriction&quot;
}

Logs:

2020-07-23 09:20:57.271  WARN 28035 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `long` from String &quot;A&quot;: not a valid Long value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `long` from String &quot;A&quot;: not a valid Long value
 at [Source: (PushbackInputStream); line: 2, column: 11] (through reference chain: myPackage.dataObjects.User[&quot;id&quot;])]

I was hoping that Spring would be able to at least provide the exception in the error message to get me by through a Minimum Viable Product iteration, so that way while it may be obtuse, a client can still ultimately understand what they did wrong, and I could add custom error handling later, but this doesn't seem to be the case?

If not, what are the methods I'd need to implement in a error/exception handler class to correctly handle validator errors?

Thanks

答案1

得分: 1

你可以在userRestriction()方法的参数中添加以下类 BindingResult bindingResult

@PostMapping("/userRestriction")
public ResponseEntity<String> userRestriction(
        @Valid @RequestBody(required = true) User user, BindingResult bindingResult)

然后在你的方法内部可以这样处理:

if (bindingResult.hasErrors()) {
    // 无论你想做什么
}

BindingResult 提供了访问和处理与 @Valid 关联的 Bean 验证的能力。

有关如何处理它的更多信息可以在这里找到:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/BindingResult.html

我建议你使用 getAllErrors() 方法,它将返回验证中的所有错误的列表。你还可以实现一个自定义异常,以在存在这些错误时抛出。

接下来,我会给你一个用于在 Spring 中实现异常处理程序的代码片段:

@ControllerAdvice
public class RestResponseEntityExceptionHandler 
 extends ResponseEntityExceptionHandler {

@ExceptionHandler(value 
  = { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity<Object> handleConflict(
  RuntimeException ex, WebRequest request) {
    String bodyOfResponse = "这应该是特定于应用程序的内容";
    return handleExceptionInternal(ex, bodyOfResponse, 
      new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}

这是我迄今为止使用过的最有用的方法,你只需要根据你的需求进行调整。你可以在这个教程中找到更多信息:https://www.baeldung.com/exception-handling-for-rest-with-spring

英文:

You can add the following class BindingResult bindingResult in the parameters of userRestriction()

@PostMapping(&quot;/userRestriction&quot;)
public ResponseEntity&lt;String&gt; userRestriction(
        @Valid @RequestBody(required = true) User user, BindingResult bindingResult)

Then inside your method you can do something like

if (bindingResult.hasErrors()) {
    //Whatever you want to do
}

BindingResult provides acces and handling to the validation of your Bean associated with @Valid

More information about how to handle it can be found here: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/BindingResult.html

I would suggest you use the method getAllErrors() which will return a list of all the errors given by the validation.
You can also implement a custom exception to be thrown when these errors exist.

Let me give you a code snippet for implementing a handler exception with Spring

@ControllerAdvice
public class RestResponseEntityExceptionHandler 
 extends ResponseEntityExceptionHandler {

@ExceptionHandler(value 
  = { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity&lt;Object&gt; handleConflict(
  RuntimeException ex, WebRequest request) {
    String bodyOfResponse = &quot;This should be application specific&quot;;
    return handleExceptionInternal(ex, bodyOfResponse, 
      new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}

This is the most useful I have used so far, you just need to adapt it to your needs. You can find further information following this tutorial: https://www.baeldung.com/exception-handling-for-rest-with-spring

huangapple
  • 本文由 发表于 2020年7月23日 23:03:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63057316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定