RestTemplate调用远程Http服务开发

一、引言:

我们在开发中经常会遇到与第三方服务交互的需求,Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端都使用RestTemplate请求restful接口服务。本文将结合具体代码详细介绍Spring RestTemplate开发。

二、设置:

2.1 setBufferRequestBody 是否是否缓冲流来存储请求体,默认true
2.2 setProxy 设置代理对象
2.3 setChunkSize 设置每次传输字节长度,与 setBufferRequestBody(false) 结合使用
2.4 setConnectTimeout 设置连接超时时间,默认 -1
2.5 setReadTimeout 设置读取内容超时时间,默认 -1
2.6 setOutputStreaming 设置Connection是否设置输出流程
2.7 setTaskExecutor 设置异步回调执行器

三、原理:

在这里插入图片描述
RestTemplate内部通过调用doExecute方法,获取ClientHttpRequest,ClientHttpRequestFactory实现了ClientHttpRequest,同时实现方法。通过ClientHttpRequest的createRequest方法选择工厂类创建对象,接着执行requestCallback.doWithRequest(request)方法,RequestCallback封装了请求体和请求头对象,也就是说在该对象里面可以拿到我们需要的请求参数。接着执行 response = request.execute()方法发送请求,最后解析response。
在这里插入图片描述

四、RestTemplate创建HTTP请求方法介绍:

RestTemplate类中通过不同的方法实现创建HTTP请求。
4.1、GET请求方法有:
在这里插入图片描述
4.2、POST请求方法有:
在这里插入图片描述
4.3、PUT、PATCH、DELETE、OPTIONS请求方法有:
在这里插入图片描述
4.4、exchange请求方法有:
在这里插入图片描述

五、不同请求方法的区别:

5.1、getForEntity/postForEntity/exchange与getForObject/postForObject最大的区别就在于返回内容不一样:getForEntity/postForEntity/exchange返回的是一个ResponseEntity,返回http全部信息。而getForObject只返回http的body部份。

getForObject/postForObject response: {"code":0,"message":"success","object”:{xxx}}
getForEntity/postForEntity/exchange response: <200,{"code":0,"message":"success","object”:{xxx}},[Connection:"keep-alive", Content-Type:"application/json", Date:"Mon, 21 Jun 2021 15:44:32 GMT", Keep-Alive:"timeout=60", Transfer-Encoding:"chunked"]>

5.2、对于post方法来说,可以比get方法多传一个request对象,请求参数可以放到请求url里面(uriVariables),也可以放到http的body里面,当然一般来说post的数据放到body里面比较正规,也比较好,因为这样数据相对不会暴露。
5.3、exchange方法可以发多种类型的HTTP请求,并且需要传request对象。
5.4、请求参数中常用的url一般都是String, 所以url参数类型是URL的用的少,可以不管。

六、源码:

废话不多说,举个栗子。
6.1、配置文件application.yml:

com:
  http:
    link: http://127.0.0.1:8081/user
    connect-timeout: 10000
    read-timeout: 60000

6.2、定义HttpServiceConfig:

@Configuration
public class HttpServiceConfig {
    public static final Logger log = LoggerFactory.getLogger(HttpServiceConfig.class);

    @Value("${com.http.link:}")
    private String httpUrl;

    @Value("${com.http.connect-timeout:}")
    private int connectTimeout;

    @Value("${com.http.read-timeout:}")
    private int readTimeout;

    //Use restTemplateBuilder prepared by Spring Boot
    @Bean
    public HttpServiceClient httpServiceClient(final RestTemplateBuilder restTemplateBuilder){
        RestTemplate restTemplate = restTemplateBuilder.rootUri(this.httpUrl)
                .setReadTimeout(Duration.ofMillis(this.readTimeout))
                .setConnectTimeout(Duration.ofMillis(this.connectTimeout))
                .build();
        HttpServiceClient httpServiceClient = new HttpServiceClient();
        httpServiceClient.setRestTemplate(restTemplate);
        return httpServiceClient;
    }
}

6.3、Http客户端实现类HttpServiceClient:

public class HttpServiceClient {
    public static final Logger log = LoggerFactory.getLogger(HttpServiceClient.class);

    public static final String GET_HTTP_RESOURCE_PATH = "/queryUserById/{userid}";
    public static final String GET_HTTP_RESOURCE_PATH1 = "/queryUserList?pageNow={pageNow}&pageSize={pageSize}";
    public static final String GET_HTTP_RESOURCE_PATH2 = "/updateUser/{id}";
    public static final String GET_HTTP_RESOURCE_PATH3 = "/createUser";
    public static final String GET_HTTP_RESOURCE_PATH4 = "/deleteUser/{id}";

    private RestTemplate restTemplate;

    public String getUserById(int userid) throws IOException {
        String response = null;
        response = this.restTemplate.getForObject(HttpServiceClient.GET_HTTP_RESOURCE_PATH,String.class,userid);
        log.info("response: "+ response);
        JSONObject responseBody = JSON.parseObject(response);
        log.info("responseBody: "+responseBody);
        String message = responseBody.getString("message");
        log.info("message: "+message);
        String user = responseBody.getString("object");
        log.info("user: "+user);
        log.info("Test boolean: "+StringUtils.isNotBlank(user));
        String username = null;
        if(StringUtils.isNotBlank(user)) {
            JSONObject jsonuser = JSON.parseObject(user);
            log.info("jsonuser: " + jsonuser);
            username = jsonuser.getString("username");
        }
        return username;
    }

    public String getUserList(int pageNow, int pageSize) throws IOException{
        ResponseEntity<String> response = null;
//        方法1:使用getForEntity方法
        response = this.restTemplate.getForEntity(HttpServiceClient.GET_HTTP_RESOURCE_PATH1,String.class,pageNow,pageSize);
//        方法2:使用exchange方法
//        HttpEntity<String> requestEntity = null;
//        response = this.restTemplate.exchange(HttpServiceClient.GET_HTTP_RESOURCE_PATH1,HttpMethod.GET,requestEntity,String.class,pageNow,pageSize);
        log.info("response: "+ response);
        JSONObject responseBody = JSON.parseObject(response.getBody());
        log.info("responseBody: "+responseBody);
        String message = responseBody.getString("message");
        log.info("message: "+message);
        String user = responseBody.getString("object");
        log.info("user: "+user);
        return user;
    }

    public String updateUser(int id, String token, User user) throws IOException{
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=UTF-8");
        headers.add("token",token);
        String body = JSON.toJSONString(user);
        log.info("body:"+body);
        HttpEntity<String> requestEntity = new HttpEntity<>(body,headers);
        ResponseEntity<String> response = null;
//        方法1:使用postForEntity方法
        response = this.restTemplate.postForEntity(HttpServiceClient.GET_HTTP_RESOURCE_PATH2,requestEntity,String.class,id);
//        方法2:使用exchange方法
//        response = this.restTemplate.exchange(HttpServiceClient.GET_HTTP_RESOURCE_PATH2,HttpMethod.POST,requestEntity,String.class,id);
        log.info("response: "+ response);
        JSONObject responseBody = JSON.parseObject(response.getBody());
        log.info("responseBody: "+responseBody);
        String message = responseBody.getString("message");
        log.info("message: "+message);
        String result = responseBody.getString("object");
        log.info("result: "+result);
        return result;
    }

    public String createUser(User user) throws IOException{
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=UTF-8");
        String body = JSON.toJSONString(user);
        log.info("body:"+body);
        HttpEntity<String> requestEntity = new HttpEntity<>(body,headers);
//        方法1:使用postForObject方法
        String response = null;
        response = this.restTemplate.postForObject(HttpServiceClient.GET_HTTP_RESOURCE_PATH3,requestEntity,String.class);
        log.info("response: "+ response);
        JSONObject responseBody = JSON.parseObject(response);
//        方法2:使用exchange方法
//        ResponseEntity<String> response = null;
//        response = this.restTemplate.exchange(HttpServiceClient.GET_HTTP_RESOURCE_PATH3,HttpMethod.POST,requestEntity,String.class);
//        log.info("response: "+ response);
//        JSONObject responseBody = JSON.parseObject(response.getBody());
//        log.info("responseBody: "+responseBody);
        String message = responseBody.getString("message");
        log.info("message: "+message);
        String result = responseBody.getString("object");
        log.info("result: "+result);
        return result;
    }

    public String deleteUser(int id) throws IOException{
        HttpEntity<String> requestEntity = null;
        ResponseEntity<String> response = null;
        response = this.restTemplate.exchange(HttpServiceClient.GET_HTTP_RESOURCE_PATH4,HttpMethod.DELETE,requestEntity,String.class,id);
        log.info("response: "+ response);
        JSONObject responseBody = JSON.parseObject(response.getBody());
        log.info("responseBody: "+responseBody);
        String message = responseBody.getString("message");
        log.info("message: "+message);
        String result = responseBody.getString("object");
        log.info("result: "+result);
        return result;
    }

    /**
     * @Description: The restTemplate to set
     * @param restTemplate
     */
    public void setRestTemplate(final RestTemplate restTemplate){this.restTemplate = restTemplate;}

}

创作不易,有说的不对的地方欢迎指出。喜欢我的文章可以一键三连。需要具体实现的demo源码的可以加我下面微信免费获取。

在这里插入图片描述

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值