浅谈外部接口调用httpClient原生方式进一步使用与各个涉及类含义及作用

简单了解调用用外部接口原生HttpURLConnection与CloseableHttpClient方式

  • 前言
  • 原生HttpClient的详细使用案例
    • 步骤
      • 新建HttpURLConnection 连接
      • 设置连接参数(请求方式、超时时间)
      • 向连接中写入请求参数
      • 读取连接返回结果
      • 关闭io连接
      • 断开url连接
      • 完整代码
  • 另一种写法
    • 代码&相关类解释
  • 注意事项
  • 总结

前言

上篇文章提到的几种调用外部接口的方式,此处针对原生httpClient方式做进一步的案例展示以及步骤讲解,同时对上篇文章中提到的原生方式中的涉及类做相应解释

原生HttpClient的详细使用案例

步骤

新建HttpURLConnection 连接

任何网络连接都需要经过socket才能连接,HttpURLConnection不需要设置socket,所以,HttpURLConnection并不是底层的连接,而是在底层连接上的一个请求。这就是为什么HttpURLConneciton只是一个抽象类,自身不能被实例化的原因。HttpURLConnection只能通过URL.openConnection()方法创建具体的实例。

 			URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();

设置连接参数(请求方式、超时时间)

            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);

向连接中写入请求参数

  • setRequestProperty()方法严格上讲是HttpURLConnection的父类—URLConnection的方法,而URL.openConnection()返回的是一个URLConnection对象,而一般我们都用他的子类HttpURLConnection去做连接和网络传输工作。
  • setRequestProperty和addRequestProperty的区别就是setRequestProperty会覆盖已经存在的key的所有values,有清零重新赋值的作用。而addRequestProperty则是在原来key的基础上继续添加其他value。
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            //   connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        	//请求头参数
            connection.setRequestProperty("Content-Type", "application/json");
            //apaas平台请求头参数,请求参数会过时
            //租户ID
            connection.setRequestProperty("xdaptenantid","300981605114052609");
            //时间戳
            connection.setRequestProperty("xdaptimestamp","1663469009699");
            //token
            connection.setRequestProperty("xdaptoken","eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjMwOTM0NjMsImlhdCI6MTY2MzA4NjI2MywieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.LnlNIRUXdpW4UTjCgv57Fx8ar4xD7aoyCnDhL4WpCe9kopVF72PNNx8ob6V-iFfeMp8P70hCpl8XhyxxtLo-vg");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取(此处是判断返回状态为200时读取返回信息并打印)

读取连接返回结果

				//获取连接
				is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();

关闭io连接

 // 关闭资源,如果该流存在则做关闭操作
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

断开url连接

虽然底层的网络连接可以被多个HttpURLConnection实例共享,但每一个HttpURLConnection实例只能发送一个请求。请求结束之后,应该调用HttpURLConnection实例的InputStream或OutputStream的close()方法以释放请求的网络资源,不过这种方式对于持久化连接没用。对于持久化连接,得用disconnect()方法关闭底层连接的socket。

// 断开与远程地址url的连接
            connection.disconnect();

完整代码

public static String doPost(String httpUrl, String param) {

        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
         //   connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

         //   setRequestProperty()方法严格上讲是HttpURLConnection的父类---URLConnection的方法,而URL.openConnection()返回的是一个URLConnection对象,而一般我们都用他的子类HttpURLConnection去做链接和网络传输工作
            connection.setRequestProperty("Content-Type", "application/json");
            // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
       //     connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");

            //apaas平台请求头参数
            //租户ID
            connection.setRequestProperty("xdaptenantid","300981605114052609");
            //时间戳
            connection.setRequestProperty("xdaptimestamp","1663469009699");
            //token
            connection.setRequestProperty("xdaptoken","eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjMwOTM0NjMsImlhdCI6MTY2MzA4NjI2MywieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.LnlNIRUXdpW4UTjCgv57Fx8ar4xD7aoyCnDhL4WpCe9kopVF72PNNx8ob6V-iFfeMp8P70hCpl8XhyxxtLo-vg");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取(此处是判断返回状态为200时读取返回信息并打印)
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源,如果该流存在则做关闭操作
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            connection.disconnect();
        }
        return result;
    }

另一种写法

(此处上篇博客中提到的原生httpClient方法中的涉及类的相关解释)

代码&相关类解释

		//CloseableHttpClient是HttpClient的实现
        CloseableHttpClient client = HttpClients.createDefault();
        //封装了URI与METHOD_NAME请求方式以及请求体
        HttpPost post = new HttpPost(url);
        String response1 = null;
        try {
            //创建请求体并添加请求参数数据(此处请求体相当于封装了我们在原生httpClient.doPost中向连接中写入请求参数,包含请求参数的格式设置如下)
            StringEntity s = new StringEntity(date);
            //此处相当于在header里头添加content-type等参数(源码)(此处不做该参数覆盖的话会默认选择 text/plain ISO-8859-1)
            s.setContentType("application/json");
            s.setContentEncoding("UTF-8");
            //设置请求体
            post.setEntity(s);
            //post请求添加请求头参数
            post.addHeader("xdaptoken", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjM0NzYxOTYsImlhdCI6MTY2MzQ2ODk5NiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.1dQA7AbOmhGQ2QRwRfi6qIjosKPj9AN34Keyu68chkLIOmsER0j5m_zq6x9VQvn-hrSyNuGaI6qJHtqjpTRTZw");
            post.addHeader("xdaptimestamp", "1663470853986");
            post.addHeader("xdaptenantid", "300981605114052609");
            //HttpResponse类表示web服务端发送回浏览器的HTTP响应,是对浏览器所发送请求的响应。
            HttpResponse res = client.execute(post);
            //为HttpEntity对象提供的静态帮助类,EntityUtils.toString(entity)处理字符集编码问题。
            //此处多嵌套了一层函数(源码).toString(res.getEntity())会去调用重载方法entityutils.tostring(httpresponse.getentity(),charset)从而去处理字符集编码问题
            response1 = EntityUtils.toString(res.getEntity());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return response1;

注意事项

  • 结束时注意断开连接同时关闭输入输出流
  • 注意使用setRequestProperty()与使用addRequestProperty的区别
  • StringEntity注意设置ContentType与ContentEncoding,相当于在header里头添加content-type等参数(此处不做该参数覆盖的话会默认选择 text/plain ISO-8859-1)

总结

HttpURLConnection 与 CloseableHttpClient 的区别如下:

  • HttpURLConnection是java的标准类,没有做封装,用起来比较原始。
  • HttpClient是开源框架,封装了访问HTTP的请求头、参数、内容体、响应等;HttpURLConnection中的输入输出流操作,在这个接口中被统一封装成了HttpPost(HttpGet)和HttpResponse。这样,减少了操作的繁琐性。

你可能感兴趣的:(服务器,java,网络)