2017-07-26 110 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()); 
     }; 
    } 
} 
相關問題