springbootJava In Mind

使用Spring RestTemplate发送HTTP请求

2019-11-19  本文已影响0人  SevenLin1993

技术公众号:Java In Mind(Java_In_Mind),欢迎关注!

Spring RestTemplate

RestTemplate是Spring用来进行HTTP访问的HTTP客户端,它遵循RESTful规范,并且简化了与HTTP服务端的通信,RestTemplate的底层默认使用JDK自带的HttpURLConnection实现,不过它也提供了自定义入口,可以通过HttpAccessor.setRequestFactory设置HTTP能力的提供方,可以是Apache HttpComponents或者是Netty或者是OkHttp等其他HTTP客户端的实现。

image.png

主要API

RestTemplate的API主要以HTTP的请求方式来命名:

DELETE
GET
HEAD
OPTIONS
POST
PUT
any

了解完简单使用一下

内置包装器

模拟服务

@RestController
@RequestMapping("/demo")
@SpringBootApplication
@Slf4j
public class DemoApplication {

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

    private List<Foo> foos = new CopyOnWriteArrayList<>();

    @GetMapping("/list")
    public ResponseEntity list(@RequestParam(value = "name", required = false) String name) {
        log.info("accept a list request...");
        boolean emptyQuery = StringUtils.isEmpty(name);
        return ResponseEntity
            .ok(foos.stream().filter(i -> emptyQuery || i.getName().equals(name)).collect(Collectors.toList()));
    }

    @PostMapping
    public ResponseEntity create(@RequestBody Foo foo) {
        log.info("accept create request,foo:{}", foo);
        // uuid
        foo.setId(UUID.randomUUID().toString());
        // add
        foos.add(foo);
        return ResponseEntity.ok(foo);
    }

    @GetMapping("/error")
    public ResponseEntity error() {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("error");
    }

    @Data
    @AllArgsConstructor
    public static class Foo {
        private String id;
        private String name;
        private int age;
    }
}

发起POST请求

//create RestTemplate
String baseUrl = "http://localhost:8080";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.TEMPLATE_AND_VALUES);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);

//request body
Map<String, String> foo = new HashMap<>();
foo.put("name", "HTTP");
foo.put("age", "18");
ResponseEntity<String> responseEntity = restTemplate.postForEntity("/demo", foo, String.class);

//parse response
if(responseEntity.getStatusCode().is2xxSuccessful()){
    log.info("success:{}",responseEntity.getBody());
}else{
    log.error("error,statusCode:{},return:{}",responseEntity.getStatusCode().value(),responseEntity.getBody());
}

发起GET请求

// create RestTemplate
String baseUrl = "http://localhost:8080";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.TEMPLATE_AND_VALUES);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);

// build uri and request
String uri = UriComponentsBuilder.fromPath("/demo/list").queryParam("name", "HTTP").toUriString();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class);

// parse response
if (responseEntity.getStatusCode().is2xxSuccessful()) {
    log.info("success:{}", responseEntity.getBody());
} else {
    log.error("error,statusCode:{},return:{}", responseEntity.getStatusCode().value(),
        responseEntity.getBody());
}

使用exchange

// create RestTemplate
RestTemplate restTemplate = new RestTemplate();
RequestEntity<Void> requestEntity = RequestEntity.get(new URI("http://localhost:8080/demo/list"))
        .build();
ResponseEntity<String> responseEntity =
        restTemplate.exchange(requestEntity, String.class);
// parse response
if (responseEntity.getStatusCode().is2xxSuccessful()) {
    log.info("success:{}", responseEntity.getBody());
} else {
    log.error("error,statusCode:{},return:{}", responseEntity.getStatusCode().value(),
            responseEntity.getBody());
}

使用execute

// create RestTemplate
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.execute("http://localhost:8080/demo/list", HttpMethod.GET, new RequestCallback() {
    @Override
    public void doWithRequest(ClientHttpRequest request) throws IOException {
        // 修改Header
        request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
    }
}, new ResponseExtractor<String>() {
    @Override
    public String extractData(ClientHttpResponse response) throws IOException {
        // 解析結果
        return IOUtils.toString(response.getBody(), StandardCharsets.UTF_8);
    }
});
log.info("result:{}", result);

错误处理

RestTemplate支持自定义错误处理,可以继承默认DefaultResponseErrorHandler,也可以实现接口ResponseErrorHandler,然后通过restTemplate.setErrorHandler()配置

// 构建RestTemplate
RestTemplate restTemplate = new RestTemplate();
try {
    ResponseEntity<String> responseEntity =
        restTemplate.getForEntity("http://localhost:8080/demo/error", String.class);
    // parse response
    if (responseEntity.getStatusCode().is2xxSuccessful()) {
        log.info("success:{}", responseEntity.getBody());
    } else {
        log.error("error,statusCode:{},return:{}", responseEntity.getStatusCode().value(),
            responseEntity.getBody());
    }
} catch (HttpStatusCodeException e) {
    log.error("error,statusCode={},body={}", e.getStatusCode(), e.getResponseBodyAsString(), e);
}

常用设置

总结

RestTemplate是Spring提供的方便HTTP请求的类,API封装也更加上层,使用起来也比较方便,并且支持对Response的多种格式的解析,支持错误处理等功能,并且提供比较灵活的底层支持,方便使用者自己选择需要的HTTP客户端的实现。

上一篇下一篇

猜你喜欢

热点阅读