2017-07-26 63 views
2

有没有一种方法可以将Spring RestTemplate与JavaBean验证API集成。 ?有没有一种方法可以将Java bean验证API与Spring RestTemplate集成

我知道有一个集成的弹簧控制器。你可以把@Valid作为请求的主体参数,如果员工无效,你将得到MethodArgumentNotValidException例外。您可以在异常处理程序类中进行处理。

@PostMapping(value = "/add", produces = APPLICATION_JSON_VALUE) 
    public ResponseEntity<String> addEmployee(
     @RequestBody @Valid Employee emp) { 

    //... 

    } 

但我要的是类似的方法来验证从春天restTemplate响应像 当我打电话这种方式 - 我想从春天获得相同(或者其他)例外。

Employee emp = template.exchange("http:///someUrl", HttpMethod.GET, null); 

我知道我可以像这样注入验证器并在响应中调用validator.validate(..)。

@Autowired 
    private Validator validator; 

但我不想每次都手动做。

+0

什么是你需要做的这个你的使用情况?从技术上讲,我不能真正想到一个你不想使用验证器对象的地方,除非它是某种代理服务......可以手动验证它,在某些情况下可以更有用。 – Chad

+0

感谢您的回复。我只是想,也许春天有一些解决方案。我有很多res的调用,我不想在restTemplate返回的每个对象上调用validate方法。 – user1321466

回答

2

您可以继承RestTemplate的子类,并在从原始数据提取它之后立即验证响应。

例子:

public class ValidatableRestTemplate extends RestTemplate { 

    private final Validator validator; 

    public ValidatableRestTemplate(Validator validator) { 
     this.validator = validator; 
    } 

    @Override 
    protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) throws RestClientException { 
     final T response = super.doExecute(url, method, requestCallback, responseExtractor); 
     Object body; 
     if (response instanceof ResponseEntity<?>) { 
      body = ((ResponseEntity) response) .getBody(); 
     } else { 
      body = response; 
     } 
     final Set<ConstraintViolation<Object>> violations = validator.validate(body); 
     if (violations.isEmpty()) { 
      return response; 
     } 

     throw new ConstraintViolationException("Invalid response", violations); 
    } 
} 

的使用则是相当简单的,只是定义你的子类为RestTemplate豆。

全样本:

@SpringBootApplication 
public class So45333587Application { 

    public static void main(String[] args) { SpringApplication.run(So45333587Application.class, args); } 

    @Bean 
    RestTemplate restTemplate(Validator validator) { return new ValidatableRestTemplate(validator); } 

    public static class ValidatableRestTemplate extends RestTemplate { 
     private final Validator validator; 

     public ValidatableRestTemplate(Validator validator) { this.validator = validator; } 

     @Override 
     protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) throws RestClientException { 
      final T response = super.doExecute(url, method, requestCallback, responseExtractor); 
      Object body; 
      if (response instanceof ResponseEntity<?>) { 
       body = ((ResponseEntity) response).getBody(); 
      } else { 
       body = response; 
      } 
      final Set<ConstraintViolation<Object>> violations = validator.validate(body); 
      if (violations.isEmpty()) { 
       return response; 
      } 

      throw new ConstraintViolationException("Invalid response", violations); 
     } 
    } 

    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 
    public static class Post { 
     @Min(2) // change to '1' and constraint violation will disappear 
     private Long id; 
     private Long userId; 
     private String title; 
     private String body; 

     @Override 
     public String toString() { 
      return String.format("Post{id=%d, userId=%d, title='%s', body='%s'}", id, userId, title, body); 
     } 
    } 

    @Bean 
    CommandLineRunner startup(RestTemplate restTemplate) { 
     return args -> { 
      final ResponseEntity<Post> entity = restTemplate.exchange("https://jsonplaceholder.typicode.com/posts/1", HttpMethod.GET, null, Post.class); 
      System.out.println(entity.getBody()); 
     }; 
    } 
} 
相关问题