场景描述

用户在provider端使用参数效验,可以对相应的参数输入要求预先进行设置,在接口实际调用前进行效验处理,达到控制参数输入标准的效果。

配置说明

  • 添加swagger-invocation-validator的pom依赖:
  1. <dependency>
  2. <groupId>org.apache.servicecomb</groupId>
  3. <artifactId>swagger-invocation-validator</artifactId>
  4. </dependency>
  • 在需要验证的代码上按照JSR 349规范添加验证器注解,如@NotNull@Min@Max等。

示例代码

  • 接口参数验证
  1. @RestSchema(schemaId = "validator")
  2. @Path("/validator")
  3. @Produces(MediaType.APPLICATION_JSON)
  4. public class Validator {
  5. @Path("/add")
  6. @POST
  7. public int add(@FormParam("a") int a, @Min(20) @FormParam("b") int b) {
  8. return a + b;
  9. }
  10. @Path("/sayhi/{name}")
  11. @PUT
  12. public String sayHi(@Length(min = 3) @PathParam("name") String name) {
  13. ContextUtils.getInvocationContext().setStatus(202);
  14. return name + " sayhi";
  15. }
  16. @Path("/sayhello")
  17. @POST
  18. public Student sayHello(@Valid Student student) {
  19. student.setName("hello " + student.getName());
  20. student.setAge(student.getAge());
  21. return student;
  22. }
  23. }
  • bean类验证
    需要在传入的Student对象前加@Valid,如上图sayHello(@Valid Student student)方法。
  1. public class Student {
  2. @NotNull
  3. private String name;
  4. @Max(20)
  5. private int age;
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. public String getName() {
  10. return this.name;
  11. }
  12. public void setAge(int age) {
  13. this.age = age;
  14. }
  15. public int getAge() {
  16. return age;
  17. }
  18. }

自定义返回异常

  • 默认的参数效验器ParameterValidator已经实现了接口ProducerInvokeExtension,按照JSR 349规范处理所需的参数验证。

如果任何参数验证失败,缺省错误是BAD_REQUEST(400, "Bad Request")。

返回错误支持自定义扩展,使用SPI机制。

  • 可以通过实现接口ExceptionToProducerResponseConverter来自定义返回的错误信息,以ConstraintViolationExceptionToProducerResponseConverter为例。

    • 实现ExceptionToProducerResponseConverter接口,重写方法,其中getOrder方法的返回结果表示该验证器的优先级,值越小优先级越高。
  1. public class ConstraintViolationExceptionToProducerResponseConverter
  2. implements ExceptionToProducerResponseConverter<ConstraintViolationException> {
  3. @Override
  4. public Class<ConstraintViolationException> getExceptionClass() {
  5. return ConstraintViolationException.class;
  6. }
  7. @Override
  8. public Response convert(SwaggerInvocation swaggerInvocation, ConstraintViolationException e) {
  9. return Response.createFail(new InvocationException(Status.BAD_REQUEST, e.getConstraintViolations().toString()));
  10. }
  11. @Override
  12. public int getOrder() {
  13. return -100;
  14. }
  15. }
  • 在META-INF下的services文件夹增加一个文件,以所实现接口x.x.x.ExceptionToProducerResponseConverter(带包名)为名,以具体实现类x.x.x.ConstraintViolationExceptionToProducerResponseConverter(带包名)为内容。