有没有办法将 java bean 验证 api 与 Spring RestTemplate 集成
Is there a way to integrate java bean validation api With Spring RestTemplate
有没有办法将 spring RestTemplate 与 JavaBean 验证集成 api。 ?
我知道 spring 控制器有一个集成。您可以将 @Valid
放在请求正文参数上,如果 Employee 无效,您将获得 MethodArgumentNotValidException
异常。你可以在异常处理程序中处理 class.
@PostMapping(value = "/add", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<String> addEmployee(
@RequestBody @Valid Employee emp) {
//...
}
但我想要的是类似的方法来验证来自 spring restTemplate 的响应,例如
当我以这种方式调用时 - 我想从 spring.
获得相同的(或其他)异常
Employee emp = template.exchange("http:///someUrl", HttpMethod.GET, null);
我知道我可以像这样注入验证器并在响应时调用 validator.validate(..)。
@Autowired
private Validator validator;
但我不想每次都手动做。
您可以子类化 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
bean即可。
完整样本:
@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());
};
}
}
有没有办法将 spring RestTemplate 与 JavaBean 验证集成 api。 ?
我知道 spring 控制器有一个集成。您可以将 @Valid
放在请求正文参数上,如果 Employee 无效,您将获得 MethodArgumentNotValidException
异常。你可以在异常处理程序中处理 class.
@PostMapping(value = "/add", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<String> addEmployee(
@RequestBody @Valid Employee emp) {
//...
}
但我想要的是类似的方法来验证来自 spring restTemplate 的响应,例如 当我以这种方式调用时 - 我想从 spring.
获得相同的(或其他)异常Employee emp = template.exchange("http:///someUrl", HttpMethod.GET, null);
我知道我可以像这样注入验证器并在响应时调用 validator.validate(..)。
@Autowired
private Validator validator;
但我不想每次都手动做。
您可以子类化 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
bean即可。
完整样本:
@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());
};
}
}