Java使用原生API调用第三方接口

使用Java原生的API调用第三方接口

背景

工作中一个系统会拆分成很多模块,分工给不同的项目组完成。那就不可避免地造成以下的情况:一个业务需要多个模块共同完成,也就是你必须调用别人的接口,合作完成客户发来的请求。那么怎么样远程调用别人模块中的接口呢?我们一起来看一看。

用到的类及方法

URL.class

注释

我们可以看看该类上面的注释

/*
类URL代表一个统一资源定位器,
一个指向万维网上“资源”的指针。
资源可以是简单的文件或目录,也可以是对更复杂对象的引用,
例如对数据库或搜索引擎的查询。
*/

根据注释我们可以大致了解URL是用来访问万维网或者说互联网上的资源的类。

简单使用用到的方法 - openConnection()

还是先看方法上的注释

/**
返回一个URLConnection实例,该实例表示与URL所引用的远程对象的连接。
每次调用此URL的协议处理程序的
UrlStreamHandler.openConnection(URL)
方法时,都会创建URLConnection的新实例。
应该注意,URLConnection实例在创建时并不建立实际的网络连接。
只有在调用URLConnection.connect()时才会发生这种情况。
如果对于URL的协议(如HTTP或JAR),存在一个公共的、专用的URLConnection子
类,
该子类属于以下包之一或它们的子包之一:java.lang、java.io、
java.util、
java.io,
则返回的连接将属于该子类。
例如,对于HTTP,将返回一个HttpURLConnection,对于JAR,
将返回一个JarURLConnection。
**/

获取一个当前地址的连接对象,但并没有建立连接。注意注释中的URLConnection实例在创建时并不建立实际的网络连接
只有在调用URLConnection.connect()时才会发生这种情况。

HttpURLConnection.class

先看类上的注释

/*
支持HTTP特定功能的URLConnection。详情参见规格。
每个HttpURLConnection实例用于发出一个请求,但是到HTTP服务器的
底层网络连接可以由其他实例透明地共享。
在请求后调用HttpURLConnection的InputStream或
OutputStream上的close()方法可能会释放与此实例关联的网络资源,
但不会影响任何共享的持久连接。
如果一个持久连接在那时处于空闲状态,
调用disconnect()方法可能会关闭底层套接字。
*/

注意注释中的每个HttpURLConnection实例用于发出一个请求,也就是一个该类对象对应一个需要发出的请求。可以看作是访问请求的具体连接。还有一点调用disconnect()方法可能会关闭底层套接字,可以将之看作成关闭连接。

setXXXX()

既然是具体连接,那肯定有很多的设置,比如请求类型是Post还是Get连接是否是长连接浏览器代理是什么是否使用缓存超时时长等等,都需要自己手动配置。具体方法大家可以看看源码。

connect()

注释

/*
打开指向此URL引用的资源的通信链接(如果尚未建立这样的连接)。
如果在连接已经打开时调用connect方法
(由值为true的connected字段指示),
则该调用将被忽略。
URLConnection对象经历两个阶段:
首先创建它们,然后连接它们。
在被创建之后,并且在被连接之前,
可以指定各种选项(例如,doInput和UseCaches)。
连接后,试图设置它们是错误的。
如有必要,依赖于连接的操作,
如getContentLength,将隐式执行连接。
*/

在这方法中与访问的接口进行连接。

基本流程

现在我们大概知道了用到的类与方法,那么具体流程应该也能理出来了:
1、创建URL
2、通过openConnection()对象获取连接的对象(HttpURLConnection
3、通过HttpURLConnection中的setXXX()方法设置连接对象的基本属性
4、调用connect()正式连接,
5、既然有连接,那么执行完任务就需要释放连接disconnect()。

具体流程如下
在这里插入图片描述
其实说简单点访问接口用的就是HttpURLConnectionURL只是用来构造HttpURLConnection的工具

具体实现

参数为键值对

 /**
         * @description
         * @author 三文鱼先生
         * @date 10:27 2022/8/15
         * @param url 接口的地址及方法名称
         * @param map 参数的键值对
         * @return java.lang.String
         **/
        public static String doPost(String url , HashMap<String , String> map) throws IOException {
            StringBuilder urlPath = new StringBuilder(url);
            //拼接参数
            if(map != null) {
                urlPath.append("?");
                map.forEach((k,v)-> {
                            try {
                                //这里的值需要编码
                                urlPath.append(k).append("=").append(URLEncoder.encode(v,"UTF-8")).append("&");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                );
                //去掉最后一个&
                urlPath.deleteCharAt(urlPath.length() - 1);
            }

            BufferedReader reader = null;
            try {
                //创建连接
                System.out.println("请求路径为:" + urlPath);
                URL urlCon = new URL(urlPath.toString());
                HttpURLConnection httpCon = (HttpURLConnection) urlCon.openConnection();
                //设置连接的基本信息
                //请求方式为Post
                httpCon.setRequestMethod("POST");
                //设置通用的请求属性
                httpCon.setRequestProperty("accept", "*/*");
                httpCon.setRequestProperty("connection", "Keep-Alive");
                httpCon.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                httpCon.setRequestProperty("Content-Type", "application/json;charset=utf-8");
                //是否可读写
                httpCon.setDoOutput(true);
                httpCon.setDoInput(true);
                //是否使用缓存
                httpCon.setUseCaches(false);
                //设置连接超时60s
                httpCon.setConnectTimeout(60000);
                //设置读取响应超时60s
                httpCon.setReadTimeout(60000);
                //正式连接
                httpCon.connect();

                //获取调用接口返回信息 等待调用接口返回
                boolean sign = true;
                while (sign) {
                    System.out.println(httpCon.getInputStream().available());
                    if(httpCon.getInputStream().available() > 0) {
                        sign = false;
                    } else {
                        //0.5s检查一次是否有执行返回
                        Thread.sleep(500);
                    }
                }

                StringBuilder result = new StringBuilder();
                reader = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
                String temp = "";
                while ((temp = reader.readLine()) != null ) {
                    result.append(temp);
                }
                httpCon.disconnect();
                System.out.println("返回数据为:" + result);
                return result.toString();
            }catch (IOException exception) {
                exception.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                if(reader != null) reader.close();
            }
            return "遇到未知错误";
        }

参数为对象

在这里插入图片描述
那我们这里给接口的参数为该对象的Json字符串即可

  /**
         * @description
         * @author 三文鱼先生
         * @date 11:23 2022/8/15
         * @param url 接口地址
         * @param objectJson 所需要的对象json
         * @return java.lang.String
         **/
        public static String doPost(String url , String objectJson) throws IOException {
            StringBuilder urlPath = new StringBuilder(url);
            //请求对应接口
            BufferedReader reader = null;
            BufferedWriter writer = null;
            try {
                //创建连接
                System.out.println("请求路径为:" + urlPath);
                URL urlCon = new URL(urlPath.toString());
                HttpURLConnection httpCon = (HttpURLConnection) urlCon.openConnection();
                //设置连接的基本信息
                //请求方式为Post
                httpCon.setRequestMethod("POST");
                //设置通用的请求属性
                httpCon.setRequestProperty("accept", "*/*");
                httpCon.setRequestProperty("connection", "Keep-Alive");
                httpCon.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                httpCon.setRequestProperty("Content-Type", "application/json;charset=utf-8");
                //是否可读写
                httpCon.setDoOutput(true);
                httpCon.setDoInput(true);
                //是否使用缓存
                httpCon.setUseCaches(false);
                //设置连接超时60s
                httpCon.setConnectTimeout(60000);
                //设置读取响应超时60s
                httpCon.setReadTimeout(60000);
                //正式连接
                httpCon.connect();

				//在这里传递对象的json
                writer = new BufferedWriter(new OutputStreamWriter(httpCon.getOutputStream()));
                //发送请求参数即数据
                writer.write(objectJson);
                //flush输出流的缓冲
                writer.flush();

                StringBuilder result = new StringBuilder();
                reader = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
                String temp = "";
                while ((temp = reader.readLine()) != null ) {
                    result.append(temp);
                }
                httpCon.disconnect();
                System.out.println("返回数据为:" + result);
                return result.toString();
            }catch (IOException exception) {
                exception.printStackTrace();
            } finally {
                if(reader != null) reader.close();
                if(writer != null) writer.close();
            }
            return "遇到未知错误";
        }

测试

测试的话 大家可以再开一个搭好的项目,然后去访问其中的接口就行了,我这里测试的是本地的一个新增数据接口。
在这里插入图片描述
具体调用其他人接口的时候记得把localhost改成对应的ip和端口就可以了

拓展

其实其中的读写数据跟我之前用套接字搭建的FTP差不多,大家也可以去看看。 Java使用Socket简单实现FTP

当然了调用三方接口不止有这一个办法,还有其他的方法调用。大家可以参考这一篇:Java 调用第三方接口方法

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值