Spring rest 控制器 @RequestParam 验证 [英] Spring rest controller @RequestParam validation

查看:63
本文介绍了Spring rest 控制器 @RequestParam 验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证请求参数.我浏览了许多博客并回答并做了同样的事情.在控制器类上添加了@Validated.

I want to validate the request param.I have gone through number of blogs and answer and did the same. Added @Validated on the controller class.

控制器中的方法:

public ResponseEntity<Employee> getHistory(
@Valid @Pattern(regexp = "^[A-Z]{2}[0-9]{6}[A-Z]{0,1}$", message = "Invalid 
emp") @NotNull(message = "input cannot be null") @RequestParam(name = "emp") 
String emp) { method body..........}

控制器建议

@ExceptionHandler(value = {ConstraintViolationException.class})
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleValidationFailure(ConstraintViolationException ex) {

  StringBuilder messages = new StringBuilder();

  for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
      messages.append(violation.getMessage() + "\n");
  }

  return messages.toString();
}

配置:

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
  return new MethodValidationPostProcessor();
}

现在做完这一切后,我收到了 404 错误."status":404,"error":"Not Found","message":"无可用消息"

After doing all this now I am getting a 404 error. "status":404,"error":"Not Found","message":"No message available"

推荐答案

您缺少 @ResponseBody 对控制器通知中方法的注解.它会导致错误,因为 Spring 试图定位模板,其名称从该方法返回为 String,因此在 REST 调用期间,您会得到如下内容:

You are missing @ResponseBody annotation over a method in controller advice. It causes an error, because Spring is trying to locate template with name returned as a String from this method, so during REST call you get something like this:

{
    "error": "Not Found", 
    "exception": "javax.validation.ConstraintViolationException", 
    "message": "No message available", 
    "path": "/history", 
    "status": 404, 
    "timestamp": 1502293311543
}

handleValidationFailure(ConstraintViolationException ex) 方法添加 @ResponseBody 注释意味着当您返回 String 时,它不是模板名称,而是响应对象本身.

Adding @ResponseBody annotation to handleValidationFailure(ConstraintViolationException ex) method means that when you return a String it's not a template name but the response object itself.

或者,您可以使用 ResponseEntity 作为通知方法中的返回类型,例如

Alternatively you can use ResponseEntity<String> as a return type in your advice method, e.g.

@ExceptionHandler(value = {ConstraintViolationException.class})
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public ResponseEntity<String> handleValidationFailure(ConstraintViolationException ex) {
    StringBuilder messages = new StringBuilder();

    for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
        messages.append(violation.getMessage());
    }

    return ResponseEntity.badRequest().body(messages.toString());
}

所以你不必用 @ResponseBody 注释方法,Spring 现在会知道你的响应不是视图名称而是响应主体本身.我希望它有所帮助.

so you don't have to annotate method with @ResponseBody and Spring will now that your response is not a view name but response body itself. I hope it helps.

我假设您调用的端点不正确.我创建了一个小型 Spring Boot 应用程序,它使用提供的信息复制您的问题:

I assume you are calling incorrect endpoint. I have created a small Spring Boot application that replicates your problem using provided information:

https://github.com/wololock/rest-validation-demo

随意克隆并运行它.运行后,您可以尝试使用以下命令调用 /history 端点:

Feel free to clone it and run it. After running you can try calling /history endpoint with:

curl "localhost:8080/history?emp=AZ000001A"

它会作为回报显示:

{"id":"AZ000001A","name":"Joe Doe"}%

如果您使用违反验证规则的 emp 调用此端点:

If you call this endpoint with emp that violates validation rules:

curl "localhost:8080/history?emp=sd"

您将得到以下回复:

{"message":"Your request contains errors","errors":[{"getHistory.arg0":"Invalid emp"}]}

我的假设是,在您的情况下,您错误地调用了端点.使用 @RestController 注释存在普遍的误解.我看到人们像 @RestController("/someRootPath") 一样使用它,然后他们希望有像

My assumption is that in your case you are calling your endpoint incorrectly. There is popular misunderstanding in using @RestController annotation. I saw people using it like @RestController("/someRootPath") and then they expected to have endpoints like

localhost:8080/someRootPath/...

这是不正确的.传递给 @RestController 注释的值无非是:

which is not correct. Value passed to @RestController annotation is nothing else than:

该值可能表示对逻辑组件名称的建议,在自动检测到组件的情况下将其转换为 Spring bean.

The value may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an autodetected component.

您可以随时检查控制台日志以查看控制器的最终映射是什么,例如

You can always check console log to see what are the final mappings for your controllers, e.g.

2017-08-09 20:40:45.663  INFO 1340 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6385cb26: startup date [Wed Aug 09 20:40:44 CEST 2017]; root of context hierarchy
2017-08-09 20:40:45.696  INFO 1340 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/history],methods=[GET]}" onto public org.springframework.http.ResponseEntity<com.github.wololock.restvalidationdemo.Employee> com.github.wololock.restvalidationdemo.EmployeeController.getHistory(java.lang.String)
2017-08-09 20:40:45.698  INFO 1340 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-08-09 20:40:45.698  INFO 1340 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-08-09 20:40:45.708  INFO 1340 --- [           main] o.s.w.s.h.BeanNameUrlHandlerMapping      : Mapped URL path [/employee] onto handler '/employee'
2017-08-09 20:40:45.714  INFO 1340 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-09 20:40:45.714  INFO 1340 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

希望能帮到你.

这篇关于Spring rest 控制器 @RequestParam 验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆