SpringBoot发送Http请求-接口对接

背景:
在做项目的时候,遇到接口对接,需要把数据发送到对方的接口中,接到项目的时候一脸懵逼,我也没搞过这样的对接,只会增删改查,看了文档,是通过http发送给对方的,对方要json数据传输。

开工:

  1. 先测试是否能推送到对方的网址
    强烈推荐大家使用postman测试接口,填写测试数据
    在这里插入图片描述
    根据文档看发送后返回的数据,如果报404那些状态码,根据状态码判断对方给的文档是否标准

  2. 利用RestTemplate发Http请求
    英文不错的可以看看:
    官方文档传送门
    英文不太行的可以看看这个
    文档传送门

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。当然你也可以 通过setRequestFactory属性切换到不同的HTTP源,比如Apache HttpComponents、Netty和OkHttp。

  1. 上代码
    3.1 pom下载
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>

3.2 RestTemplate配置
配置application.yml

http_pool:
  max_total: 200
  default_max_per_route: 100
  connect_timeout: 5000
  connection_request_timeout: 1000
  socket_timeout: 65000
  validate_after_inactivity: 2000

新建ApplicationValues.java
这个是读取配置中的参数方法

package com.ktamrinterface.config;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @description 获取Application配置数据
 * @date
 */

@Component
public class ApplicationValues {

    @Value("${http_pool.max_total}")
    private int maxTotal;

    @Value("${http_pool.default_max_per_route}")
    private int maxPerRoute;

    @Value("${http_pool.connect_timeout}")
    private int connTimeOut;

    @Value("${http_pool.connection_request_timeout}")
    private int connReqTimeOut;

    @Value("${http_pool.socket_timeout}")
    private int socketTimeout;

    @Value("${http_pool.validate_after_inactivity}")
    private int inactivity;

    public int getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public int getMaxPerRoute() {
        return maxPerRoute;
    }

    public void setMaxPerRoute(int maxPerRoute) {
        this.maxPerRoute = maxPerRoute;
    }

    public int getConnTimeOut() {
        return connTimeOut;
    }

    public void setConnTimeOut(int connTimeOut) {
        this.connTimeOut = connTimeOut;
    }

    public int getConnReqTimeOut() {
        return connReqTimeOut;
    }

    public void setConnReqTimeOut(int connReqTimeOut) {
        this.connReqTimeOut = connReqTimeOut;
    }

    public int getSocketTimeout() {
        return socketTimeout;
    }

    public void setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
    }

    public int getInactivity() {
        return inactivity;
    }

    public void setInactivity(int inactivity) {
        this.inactivity = inactivity;
    }


}


新建RestTemplateConfig.java
这个是配置我们的底层http客户端(这里我们使用apache的client

如何配置:

Spring提供了HttpComponentsClientHttpRequestFactory可以通过该方法来配置我们的http客户端

package com.ktamrinterface.config;


import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * @description http工厂配置
 * @date
 */
@Configuration
public class RestTemplateConfig {

    @Autowired
    private ApplicationValues appValues;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(httpRequestFactory());
    }

    @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    @Bean
    public HttpClient httpClient() {
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(appValues.getMaxTotal());
        connectionManager.setDefaultMaxPerRoute(appValues.getMaxPerRoute());
        connectionManager.setValidateAfterInactivity(appValues.getInactivity());
        RequestConfig requestConfig = RequestConfig.custom()
                //服务器返回数据(response)的时间,超过抛出read timeout
                .setSocketTimeout(appValues.getSocketTimeout())
                //连接上服务器(握手成功)的时间,超出抛出connect timeout
                .setConnectTimeout(appValues.getConnTimeOut())
                //从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .setConnectionRequestTimeout(appValues.getConnReqTimeOut())
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }
}

发送请求
RestTemplate对于不同的请求方式提供了不同的函数、我把官方的图贴一下、下面我会把常用的跟大家说一下图片传送门
在这里插入图片描述

package com.ktamrinterface.quartz;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

public class TuiSongJob2 {


    @Autowired
    private RestTemplate restTemplate;

    /**
     * 生成post请求的JSON请求参数
     *
     * @param yinJiang 需要发送的json数据
     * @return
     */
    protected HttpEntity<Map> generatePostJson(Map<String, Object> yinJiang) {

        //如果需要其它的请求头信息、都可以在这里追加
        HttpHeaders httpHeaders = new HttpHeaders();
        MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        httpHeaders.setContentType(type);
        HttpEntity<Map> httpEntity = new HttpEntity<>(yinJiang, httpHeaders);
        return httpEntity;
    }

    /**
     * 生成get参数请求url
     * 示例:https://0.0.0.0:80/api?u=u&o=o
     * 示例:https://0.0.0.0:80/api
     *
     * @param protocol 请求协议 示例: http 或者 https
     * @param uri      请求的uri 示例: 0.0.0.0:80
     * @param yinJiang   请求参数
     * @return
     */
    public String generateRequestParameters(String protocol, String uri, Map<String, Object> yinJiang) {
        StringBuilder sb = new StringBuilder(protocol).append("://").append(uri);
        if (yinJiang!=null) {
            sb.append("?");
            for (Map.Entry map : yinJiang.entrySet()) {
                sb.append(map.getKey())
                        .append("=")
                        .append(map.getValue())
                        .append("&");
            }
            uri = sb.substring(0, sb.length() - 1);
            return uri;
        }
        return sb.toString();
    }

    /**
     * post请求、请求参数为json
     *
     * @param yinJiang 需要发送的json数据
     * @param sendUrl  填写对方的接口地址
     * @return
     */
    protected String sendPost(Map<String, Object> yinJiang, String sendUrl) {
        String uri = sendUrl;
        ResponseEntity<String> yinJiangResponseEntity = restTemplate.postForEntity
                (
                        uri,
                        generatePostJson(yinJiang),
                        String.class
                );

        String body = yinJiangResponseEntity.getBody();

        return body;
    }

    /**
     * get请求、请求参数为?拼接形式的
     * <p>
     * 最终请求的URI如下:
     * <p>
     * http://127.0.0.1:80/?name=张耀烽&sex=男
     *
     * @return
     */
    public String sendGet(String protocol, String uri, Map<String, Object> yinJiang) {


        ResponseEntity responseEntity = restTemplate.getForEntity
                (
                        generateRequestParameters(protocol, uri, yinJiang),
                        String.class
                );
        return (String) responseEntity.getBody();
    }
}

  1. 调用

在发送完成之后对方会给我返回一个json结果,我要把这个json读取出来,我导入了一个json工具类

        <!-- JSON工具类 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

接下来就是调用了,我只是贴出部分主要代码
我要发送这样的格式的数据所以我就这样写
在这里插入图片描述

 ObjectMapper mapper = new ObjectMapper();
   Map<String, Object> m2 = new HashMap<>();

        for(int i = 1;i<=n;i++){
            try {
                //取出每n次的数据
                list2 = list.stream().skip((i * uploadNumber) - uploadNumber).limit(uploadNumber).collect(Collectors.toList());
                
				m2.put("cbyId",cbyId);
                m2.put("cbyName",cbyName);
                m2.put("cbyCode",cbyCode);
                m2.put("sMon",sMon);
                m2.put("records",list2);
                //这里就调用上面的发送方法
                String s = sendPost(m2, sendUrl);
                //对返回后的json数据解析
                mInfo = mapper.readValue(s, Map.class);
            }catch (Exception e){
                System.out.println("上传数据发生异常:"+e.getMessage()+",第"+i+"次失败");
                break;
            }

在这里插入图片描述
发送成功后的,对方返回的消息,结果展示如下
在这里插入图片描述

如果不成功欢迎大家留言,如果发现博文中发现有错误,欢迎各位老鸟多多指教一二。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Bug

谢谢老板,老板大气,老板硬邦邦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值