有没有一种方法可以将Java bean验证api与Spring RestTemplate集成在一起 [英] Is there a way to integrate java bean validation api With Spring RestTemplate

查看:74
本文介绍了有没有一种方法可以将Java bean验证api与Spring RestTemplate集成在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以将spring RestTemplate与JavaBean验证api集成在一起.?

Is there a way to integrate spring RestTemplate with JavaBean validation api. ?

我知道弹簧控制器有一个集成.您可以将 @Valid 放在请求正文参数上,如果Employee无效,您将获得 MethodArgumentNotValidException 异常.您可以在异常处理程序类中进行处理.

I know there is a integration for spring controller. you can put @Valid on request body param and if Employee is not valid you will get MethodArgumentNotValidException exception . which you can handel in exception handler class.

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

    //...

  }

但是我想要的是类似的方法来验证来自spring restTemplate的响应,例如当我这样称呼时-我想从spring中获得相同(或其他)异常.

But what I want is similar way to validate response from spring restTemplate like when I call this way - I want to get same(or maybe other) exception from spring.

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

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

I know I can inject validator like this and call validator.validate(..) on reponse.

  @Autowired
  private Validator validator;

但是我不想每次都手动进行.

But I do not want to do it each time manually.

推荐答案

您可以将 RestTemplate 子类化,并在从原始数据中提取响应后立即验证响应.

You can subclass RestTemplate and validate the response just right after it was extracted from raw data.

示例:

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.

The usage then is quite simple, just define your subclass as 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());
        };
    }
}

这篇关于有没有一种方法可以将Java bean验证api与Spring RestTemplate集成在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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