与外系统连接时,需要考虑的问题

目录

■注意点

1.用户名密码设置的安全性

2.连接超时的问题

3.各种特殊情况的处理

4.Log情报的输出

5.错误的分类

6.发生错误时如何处理 (根据实际业务需求来定。)

7.外系统是否需要登录

8.外系统是内部网络中的系统,还是外部网络中的系统。(即,是否真的需要https)

9.与外部系统连接时,要考虑【认证】问题。

10.自身服务器的运行时间段, 调用WebAPI的服务器的运行时间段

11.注意 资源的  【关闭 close】

12.Header中,不能设置汉字情报。

13.如果使用ASE加密,要注意加密模式(两方系统之间,提前商量好)

14.提供WebAPI的服务方,是否有多个服务器。

15.要写入设计书中的内容

16.如果涉及数据加密解密,提前提供加密文件,看对方能否正常解密。

17.【认证相关问题】外系统,外系统测,是否有访问限制的设定,比如403

18.【认证相关问题】证明书(证明书有两种,客户端证明书,服务器端证明书)

19.【认证相关问题】从哪里发起请求,Web服务端后台?,Web服务器端前台(要考虑浏览器同源策略,对方的WebAPI侧要做相应的设定)?,服务器批处理的Batch?

20.【代理相关】【proxy】链接外系统时,是否要使用代理服务器进行连接

21.对API进行压力测试,可以使用工具【SoapUI】

-------------查看代理设置(通过Edge)

22.影响API运行效率的因素

■注意点----【作为 WebAPI提供方 的 观点】

1.应该能在2秒之内,处理完完了,并作出相应。

2.提交对WebAPI的接口IF进行 商议(认识一致):★★非常重要!!!

3.对调用方,做一些使用上的限制要求。

4.压力测试的具体内容

■相关知识

■提供服务的WebAPI代码 (RestFul)

处理响应方法体

扩展01:添加【请求 、响应】对象 ⇒ 获取 、设置 Header信息

扩展02:@ResponseBody

RequestBean

ResponseBean

■调用服务的请求方代码

■更多代码(请求方,响应方)


==============

■注意点

1.用户名密码设置的安全性

        想都不用想,一定不能写在代码里面

        同时要考虑是否有必要对密码进行加密。

        (比如,密码作为服务器参数进行配置,我们可以把用户名以及密码明文写在配置中吗?) 

          Java中的System.getProperty()设置参数的方法_sun0322的博客-CSDN博客_system.getproperty 设置

         加密的时候,可以考虑AES加密(Advanced Encryption Standard)

          外部系统连接SFDC,获取SFDC侧的数据_sun0322的博客-CSDN博客  (文章中的No.20)

          使用AES加密时,加密解码需要一个KEY,这个KEY我们配置到哪里。

          这都是我们需要考虑的问题。

2.连接超时的问题

       一定要设置TimeOut时间

       本次使用HttpClient连接外系统,不指定超时时间时,等了80多秒。。。

・ 同时要【注意】超时种类!!!

======

HttpClient 超时设置_httpclient 设置超时时间_王俊超_的博客-CSDN博客

httpclient 4.5版本 有三种  超时

1.connectTimeOut
2.socketTimeOut
3.connectionRequestTimeOut

======

・同时要【理解】请求超时 与 404 的区别

=========
 ・请求超时:发送请求,但一段时间内,无法得到服务器响应时,就会发生请求超时。 (408)
 ・404:请求不存在的资源时。

=========

1. 连接超时(Connect Timeout):这是建立 TCP 连接的超时时间。当需要连接到服务器时,HttpClient 将等待一定时间来建立连接。如果在超时时间内未能建立连接,HttpClient 将抛出连接超时异常。

2. 读取超时(Socket Timeout):这是从服务器读取数据的超时时间。当已经建立连接并发送请求到服务器后,HttpClient 将等待一定时间来读取服务器的响应数据。如果在超时时间内未能读取到响应数据,HttpClient 将抛出读取超时异常。

3. 连接请求超时(Connection Request Timeout):这是从连接池中获取连接的超时时间。当需要从连接池中获取连接时,如果连接池中没有可用的连接,HttpClient 将等待一定时间来获取一个可用的连接。如果在超时时间内未能获取到连接,HttpClient 将抛出连接请求超时异常。

这三种超时时间的作用不同:

- 连接超时主要影响的是建立连接的时间,如果服务器响应时间很长或网络较差,可能会导致连接超时异常;
- 读取超时主要影响的是读取服务器响应数据的时间,如果服务器响应时间比较长,可能会导致读取超时异常;
- 连接请求超时主要影响的是从连接池中获取连接的时间,如果连接池中没有可用的连接或连接池满了,可能会导致连接请求超时异常。

在使用 HttpClient 的过程中,可以根据具体需求来设置这三种超时时间,以确保与服务器通信的稳定性和可靠性。

=============

setConnectTimeout(MilSec):获取连接超时时间。如果该参数没有设置,那么默认的超时间在不同的OS下是不同的,Windows大概20s(什么也不设置,实测过,差不多是这个值) ,Linux大概180s。为了在访问不存在网页造成的访问阻塞,建议访问时设置此参数。 

setSocketTimeout(MilSec):获取响应数据需要等待的时间。如果访问服务器迟迟不返回数据,就会抛出SocketTimeoutException异常信息。(什么也不设置,实测过,120秒没有

问题,应该没有时间限制)
 

===

3.各种特殊情况的处理

       用户名密码没有取得时如何处理

       发生异常时如果处理

             ・ 连接不上(连接超时)

             ・ 对于返回的数据处理时,发生异常(IOException)

       HTTP_STATUS_CODE 不是「200」时如何处理

      对于异常的捕获处理

            ・ 确认能捕获所有异常,不能因为连接了外系统,发生想定外情况,系统就崩了

                (目前我的做法时,在处理函数的里面,捕获能预测的异常,对于函数,声明为throws Excepton

                    调用函数时,再次捕获异常,确保即使发生想定外的情况,程序也能正常运行。)

4.Log情报的输出

     很有必要,当发生问题时,有助于我们的调查

5.错误的分类

     1.网络问题,连接超时 (网络问题)

     2.无法访问,404 (URL配置错误)

     3.认证问题,404之外的400系列错误

     4.HttpClient 使用时的异常

     5.客户端证明书造成的问题

     6.服务器端证明书造成的问题

     7.成功连接到WebAPI系统,返回值500系列

     8.成功连接到WebAPI系统,返回值200,但是States不是正确的状态

6.发生错误时如何处理 (根据实际业务需求来定。)

    直接ErrorLog,后续业务正常处理?

    Retry(尝试重新连接)?

7.外系统是否需要登录

     (这个严格意义上说,因该是WebAP的提供方,在设计时需要考虑的问题)

   最近我们访问D系统的WebAPI,D系统平时使用时,是需要登录才能使用的,

  这就造成了,我们访问D系统的WebAPI后,Reponse响应的是D系统的登录画面。
    (估计是因为没有登录,D系统中有Filter对是否登录进行Check。)

  

8.外系统是内部网络中的系统,还是外部网络中的系统。(即,是否真的需要https)

如何外部系统是内部网络中的系统,通过http也可以访问。

那么要让提供WebAPI的外部系统确认一下,

他们提供的WebAPI是否接受HTTP访问这种方式。(主要是从系统安全角度考虑)

9.与外部系统连接时,要考虑【认证】问题。

目前做的这个案件,访问D系统,

D系统和我们的系统在同一个内网之中,

可以通过http直接访问,而且没有任何认证就可以直接访问,真的可以码?!

关于【认证】方式,有很多,下面是工具postman中,可以使用的一些认证方式

====

什么是JWT?OAuth2以及Bearer Token基本解析_S1aine的博客-CSDN博客

 ====

10.自身服务器的运行时间段, 调用WebAPI的服务器的运行时间段

  自身服务运行时间段内,对方服务器是否也一直运行。

11.注意 资源的  【关闭 close】

・示例代码

java处理,调用外系统的 WebAPI(https请求)时,相关知识整理_java调用webapi_sun0322的博客-CSDN博客

・为什么选择使用CloseableHttpClient,而不是HttpClient,他们俩有什么区别

============

【项目实战】为什么我选择使用CloseableHttpClient,而不是HttpClient,他们俩有什么区别?_closeablehttpclient 和httpclient的区别_本本本添哥的博客-CSDN博客

・HttpClient没有close方法。无法关闭连接请求。
・HttpClient是单例模式,只能在一个应用中使用一个HttpClient实例;

============

・CloseableHttpResponse用完需要手动关闭吗

========

CloseableHttpResponse用完需要手动关闭吗_cg_Amaz1ng的博客-CSDN博客

不用。 (前提是调用了EntityUtils去读取过了。)

========

12.Header中,不能设置汉字情报。

header中,只能传输base64形式的编码。

如果要传输汉字情报,只能放在JSON中进行传输。

或者进行转码:  (不推荐使用!)

header中只能传输英文,如果需要传输中文,发放方需要使用URLEncoder.encode(“我是汉字”,"UTF-8") 进行编码,接收方需要使用URLDecoder.decode("待解析字符串", "UTF-8")进行解码!

URL地址中的中文乱码问题的解决_url中文会乱码_bladestone的博客-CSDN博客

URL转码(之前写的Ajax的代码中,使用过)

====

。。。
var url = "/sxz/messageboard/adminReply.action?id=" + prefixID+"&muReplay="+muReply;
url=encodeURI(url); 
。。。

原始的Ajax请求方式 (XMLHttpRequest)_ajax原始_sun0322的博客-CSDN博客

====

13.如果使用ASE加密,要注意加密模式(两方系统之间,提前商量好)

AES加密、MD5、SHA256等散列生成(java代码)_sun0322的博客-CSDN博客

14.提供WebAPI的服务方,是否有多个服务器。

  多个服务器,如果直接访问内网地址,有可能负载平衡的设置没有效果。

 当然,也可能有内网的负载平衡服务器地址。

 如果访问内网时,无法实现负载平衡,提前商量好,可否只用一个Server

15.要写入设计书中的内容

  加密方式

  各个环境的地址,端口号(IT,ST、本番、災対)

  各个环境的密钥(IT,ST、本番、災対)

             AES KEY

             AES CBC MODE 的 IV KEY

  处理的 Timeout时间

 Request

       Header

       Body    (数据形式,不如JSON; 要不加密,比如AES)

 Response

      Header中设置的内容

      Body中设置的内容 (Resoponse StatusCode,ErrorCode,ErrorMessage)

  运行时间(几点到几点)

  各个情况返回的 HTTP STATUS CODE

16.如果涉及数据加密解密,提前提供加密文件,看对方能否正常解密。

比如ASE算法
  有好多种因素决定,
    ・KEY的长度
    ・ AES五种加密模式(ECB、CBC、CTR、OCF、CFB)的选择
    ・【IV】(初始化向量),是否使用

AES加密、MD5、SHA256等散列生成(java代码)_md5密钥生成_sun0322的博客-CSDN博客

===

17.【认证相关问题】外系统,外系统测,是否有访问限制的设定,比如403

比如,外系统,为了:让一些地址能正常访问,另外一些地址禁止访问,返回403,

做了如下设定

使用 Apache 的 mod_rewrite 模块和 .htaccess 文件来进行配置。以下是一种常见的做法:

  1. 打开 Apache 的配置文件(如 httpd.conf)并启用 mod_rewrite 模块。找到以下行并确保其没有被注释掉:

    LoadModule rewrite_module modules/mod_rewrite.so
    
  2. 在需要进行限制的目录下创建一个名为 .htaccess 的文件(如果已存在,则直接编辑)。

  3. 在 .htaccess 文件中添加以下代码:

    RewriteEngine on
    
    # 允许访问的地址
    RewriteCond %{REQUEST_URI} !^/allowed-url-1 [NC]
    RewriteCond %{REQUEST_URI} !^/allowed-url-2 [NC]
    # 添加更多所需的允许访问的地址
    
    # 禁止访问的地址
    RewriteRule ^ - [F]
    

    上述代码中,将 /allowed-url-1/allowed-url-2 设为允许访问的地址,你可以根据需要添加更多的 RewriteCond 条件来定义允许访问的地址。最后的 RewriteRule ^ - [F] 表示禁止访问其余所有地址,并返回 403 状态码。

  4. 保存 .htaccess 文件并重新加载 Apache 配置。

现在,只有在被允许的地址下访问时,Apache 才会返回正常页面。而对于禁止访问的地址,Apache 会返回 403 错误。

xxx

18.【认证相关问题】证明书(证明书有两种,客户端证明书,服务器端证明书)

java处理,调用外系统的 WebAPI(https请求)时,相关知识整理_java调用webapi_sun0322的博客-CSDN博客

xxx

19.【认证相关问题】从哪里发起请求,Web服务端后台?,Web服务器端前台(要考虑浏览器同源策略,对方的WebAPI侧要做相应的设定)?,服务器批处理的Batch?

===

xxx

20.【代理相关】【proxy】链接外系统时,是否要使用代理服务器进行连接

・如果API是在同一个局域网内的系统,一般不需要使用代理。

・如果API是在同一个局域网内的系统,如果使了错误的代理,有可能造成403拒绝访问。

・如果API是外网的系统,一般服务器有安全设定,不能直接访问外网,如果访问外网,需要设定代理之后,才能访问外网。

例,使用RestTemplate指定代理

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.net.Proxy;

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {
        // 创建代理
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy_host", proxy_port));
        
        // 创建并设置ClientHttpRequestFactory
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setProxy(proxy);
        
        // 创建RestTemplate并设置ClientHttpRequestFactory
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        
        return restTemplate;
    }
}

21.对API进行压力测试,可以使用工具【SoapUI】

一些很好的工具软件~_capt_st-CSDN博客

最近使用SoapUI对自己的WebAPI进行压力测试时,访问时竟然出现403错误。

解决:关闭代理,问题解决。

有时,指定代理后,反而造成403,
原因:
本来一些内网的访问,无需代理,
但是代理能访问的URL是有限制的,使用代理访问内网地址,会造成403.
(有时,一些工具,默认使用代理,比如SoapUI,启动后默认使用代理。。。)

====

curl 指定代理访问

-x, --proxy [protocol://]host[:port]

curl --proxy http://proxy.xxx.xxx.com:443 http://restFulSercer/getUserInfo
curl -x http://proxy.xxx.xxx.com:443 http://restFulSercer/getUserInfo

=====

-------------查看代理设置(通过Edge)

=====

・下面黄色框标记的是,代理服务器的设置(一般公司电脑都有代理设置)。

・红色标记的是, 访问时,不使用 代理服务器的网址。(一般内网地址比如10.*, 192.*等都不使用。)

・内网访问如果使用代理服务器,并且你的代理服务器有某些访问限定,那么就会出现403

====

==================

=====

22.影响API运行效率的因素

目前已知因素:查询时,抽出数据的件数

现象:

    调用对方API,从72万条数据中,抽出1800件数据,耗时1.6秒

    调用对方API,从72万条数据中,抽出450件数据,耗时0.4秒

结论:

 ・抽出件数的数量,与花费的时间,成正比。

 ・查询效率,受整体件数影响不大。

对应方针:

・如果对于相应时间有要求,不要一次从对方数据对方获取大量数据。

------------------------------------------------

根据:

    在API侧查看log发现,主要的时间消耗在从数据库取得数据上,

        比如,

         总共处理时间:1650毫秒

            其中,SQL处理时间:1620毫秒

       即使给查询时条件字段加上索引,效果也不大,

       但是,通过增加条件,减少抽出数据的件数后,效果明显,

                         ⇒  抽出件数的数量,与花费的时间,成正比。

==============

=====================

■注意点----【作为 WebAPI提供方 的 观点】

1.应该能在2秒之内,处理完完了,并作出相应。

   前提条件:
         ・调用方,不能一次抽出过多数据,比如超过1000条

2.提交对WebAPI的接口IF进行 商议(认识一致):★★非常重要!!!

首先,联络时,明确记述【依赖确认:下面内容认识是否一致】,

------------

   ・01.IF中定义的项目【有无】:上流系统能否全部提供

   ・02.IF中定义的项目【长度】:和上流系统的认识是否一致,  ★★★尤其是最大位数★★★

        最大位数会影响到,显示,DB存储 

   ・03.IF中定义的项目【格式】:和上流系统的认识是否一致
                                      比如、日期,是下面的哪一种
                                                   yyyy-MM-dd HH:mm:ss

                                                   yyyy/MM/dd HH:mm:ss.SSS

                                                   yyyy/MM/dd HH:mm:ss

                                                   yyyy/MM/dd

   ・04.IF中定义的项目【是否补位】:
                                      比如、月是2位,连携的时候,是4还是04
                                      比如、年龄是3位,18岁连携的时候,是18还是018
                                              ↑如果年龄在数据库中,是 char(3)、我们一般希望是018
                                      比如、金额,是否需要补零(一般不需要用)。

   ・05.IF中定义的项目【数据类型】: int, String, Object

   ・06.IF中定义的项目【数据单位】: 主要针对金额项目, 还是 万元

   ・07.IF中定义的项目【字符类型】:全角カナ,半角カナ(半角大文字,半角小文字)

   ・08.IF中定义的项目【List项目】【件数】:是否有指定固定件数

   ・09.IF中定义的项目【List项目】【顺序】: 是否有指定固定顺序

   ・10.IF中定义的项目【空值】: ①" "、②null、③[]、④{}  空值时,选用哪种方式设定

   ・11.IF中定义的项目【空值】:空值时,这个值能否从我们系统自身取得。

     IF定義の設計時、定义了、但是使用中发现上流在业务中无法设定,

                   要考虑一下,我们系统自身是否有这个数据的保存。

                   要考虑一下,要考虑一下,这个项目,在业务上的的含义到底是什么!!!

                                             ↑ 考慮時、思い込む、だめです!!!

                   下面链接,记录了,思い込む 的后果

      https://blog.csdn.net/sxzlc/article/details/135963207

   ・12.IF中定义的项目【必须/任意】:和上流系统的认识是否一致

   ・13.IF中定义的项目【必须】:值或项目不存在时,是否也连携一个空值的项目过来。

                                                   比如,item_50不存在,也要求连携  "item_50" :""

   ・14.IF中定义的项目【特殊要求】:

                  ・比如1:

                         API提供 《(初次)登录》《更新》两个操作,不同操作,「登录更新Flg」项目区分。

        在更新时,有「预先指定状态」项目,要保持前后一致,即不能在更新时更改。

                  ・比如2:

                       只允许《(初次)登录》一次。(后来商讨,运行多次 《(初次)登录》,采用 Merge Into 实现)

                       只允许《更新》一次。

                  ・比如3:
                       特殊的编辑处理,两个项目合并为一个项目,值「項目1の値-項目2の値」

   ・15.IF中定义的项目【】:
                   参照之前的某个处理,作出新的API设计书时,代码和设计书的逻辑是否一致
                    比如,上面绿色的「比如3:」的特殊处理,代码有,设计书没有。。。

-----------------------------------------------

然后,在补上一句,除了上面内容之外,对于IF的定义,还有什么在意的地方.

3.对调用方,做一些使用上的限制要求。

比如:
         ・调用方,不能一次抽出过多数据,比如超过1000条

         ・调用方,添加条件,尽可以只抽出有效数据(如:查询日期开始算,90天之内的数据)。

4.压力测试的具体内容

Batch设计注意点 与 奇怪现象调查-CSDN博客

5.xxx

====

-------------------

■相关知识

HttpClient设置时间超时(本次采用4.3,已验证好用)

4.3之前
client.setConnectionTimeout(10000); 
client.setTimeout(10000);

4.3

// 连接时间超时
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,10000); 

// 和读取数据超时
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,10000);

4.3之后
RequestConfig requestConfig =  RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
httpGet.setConfig(requestConfig);

-------------------------------------

・连接方法

https://www.cnblogs.com/jichi/p/11331485.html

・连接超时参数解读

网络超时设置connectionTimeout和SoTimeout的区别_熊猫卓的博客-CSDN博客_so_timeout

-------------------------------------

■提供服务的WebAPI代码 (RestFul)

处理响应方法体

package com.sxz.controler;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sxz.entity.TestRequest;
import com.sxz.entity.TestResponse;

@RestController
public class TestController {

	@PostMapping(value = "/createUser", 
			consumes = "application/json;charset=utf-8",
			produces = "application/json;;charset=utf-8")
    public TestResponse add(@RequestBody TestRequest test) {
    	TestResponse response = new TestResponse();
    	
    	String userName = test.getUserName();
    	String age = test.getUserAge();
    	
    	String classPath = TestController.class.getClassLoader().getResource("").getPath();

		response.setMessage(userName + "---" + age + "---" + classPath);
		response.setStatus("1");
    	
        return response ;
    }
}

扩展01:添加【请求 、响应】对象 ⇒ 获取 、设置 Header信息

package com.sxz.controler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.sxz.entity.TestRequest;
import com.sxz.entity.TestResponse;

@RestController
public class TestController {

	@PostMapping(value = "/createUser", 
			consumes = "application/json;charset=utf-8",
			produces = "application/json;;charset=utf-8")
	public TestResponse add(@RequestBody TestRequest test, 
			HttpServletRequest req, 
			HttpServletResponse resp) {
    	TestResponse response = new TestResponse();
    	
    	String userName = test.getUserName();
    	String age = test.getUserAge();
    	
    	String classPath = TestController.class.getClassLoader().getResource("").getPath();
    	
        String value1 = req.getHeader("key1");

    	resp.addHeader("key1", value1);
    	resp.addHeader("key2", "value2");
    	resp.addHeader("key3", "汉字乱码");
    	
		response.setMessage(userName + "---" + age + "---" + classPath);
		response.setStatus("1");
    	
        return response ;
    }
}

===

PostMan请求

PostMan响应

=== 

扩展02:@ResponseBody

・@ResponseBody 的作用其实是将 java 对象转为 json 格式的数据。
・@ResponseBody 的输出格式,默认情况取决于客户端的 Accept 请求头。

・Accept 请求头:
    下面请求代码中   ⇒  【httpPost.addHeader("Content-Type", "application/json;charset=utf-8");】

=====

=====

RequestBean

package com.sxz.entity;

import org.codehaus.jackson.annotate.JsonProperty;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestRequest {
 
	// JackSon 默认是通过驼式命名
	
    @JsonProperty("userName")
    private String userName;
 
    @JsonProperty("userAge")
    private String userAge;
    
    // {"user_name":"sss", "user_age":"22"}
 
}

=====

ResponseBean

package com.sxz.entity;

import lombok.Data;

@Data
public class TestResponse {
	 
    private String status;
 
    private String message;
 
    @Override
    public String toString() {
        return "TestResponse [status=" + status + "message=" + message + "]";
    }
}

■调用服务的请求方代码

package com.sxz.study.http;

import java.io.IOException;
import java.net.ConnectException;
import java.nio.charset.StandardCharsets;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HttpClientTest {

	public static void main(String[] args) {
		post();
	}

	public static void post() {
		log.info("Begin--001");

		// 创建httppost
//		HttpPost httpPost = new HttpPost("http://10.10.10.195:8081/testRest/createUser");
		HttpPost httpPost = new HttpPost("http://localhost:8081/testRest/createUser");

		// 解决httpclient超时设置不生效,附各版本设置方法
		// https://www.aqwdzy.com/content/99

		// Set Timeout Config
		RequestConfig requestConfig = RequestConfig.custom()
				// .setConnectionRequestTimeout(1033) // 指从连接池获取连接的timeout超出预设时间
				// 如果连接池里连接都被用了,且超过设定时间,
				// 就会报错 connectionrequesttimeout,会抛出超时异常
				// 如果是非连接池的话,该参数暂时没有发现有什么用处。
				//
				.setConnectTimeout(10000) // connectTimeOut就是指在进行三次握手行为时所设置的超时
											// 就是http请求的三个阶段,
											// 一:建立连接;
											// 二:数据传送;
											// 三,断开连接。
											//
				                            // "http://localhost:8081/testRest/createUser" 時無効
				                            //
				.setSocketTimeout(22000) // 指客户端从服务器读取数据的timeout超出预期设定时间,
											// 超出后会抛出SocketTimeOutException
				.build();
		httpPost.setConfig(requestConfig);

		// Set Header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");

		// Set Body
		String jsonStr = "{\"userName\":\"张三\", \"userAge\":\"22\"}";
		httpPost.setEntity(new StringEntity(jsonStr, StandardCharsets.UTF_8));

		log.info("Begin--002");

		try (
				// 创建默认的httpClient实例.
				CloseableHttpClient httpclient = HttpClients.createDefault();
				// Send Post
				CloseableHttpResponse response = httpclient.execute(httpPost);) {

			// 获取响应 Status
			Integer statusInt = response.getStatusLine().getStatusCode();

			log.info("-----STATUS CODE :----");
			log.info(statusInt.toString());
			// 获取响应 Body
			HttpEntity httpEntity = response.getEntity();
			String responseContent = EntityUtils.toString(httpEntity, "UTF-8");

			// Response Header Info
			String headerValue = response.getFirstHeader("key2").getValue();
			log.info("----Response Head-----");
			log.info(headerValue);
			
			log.info("----Response Body-----");
			log.info(responseContent);
			


		} catch (ClientProtocolException e) {
			log.error("ClientProtocolException");
			e.printStackTrace();
		} catch (HttpHostConnectException e) {
			log.error("HttpHostConnectException");
			e.printStackTrace();
		} catch (java.net.UnknownHostException e) {
			log.error("UnknownHostException");
			e.printStackTrace();
		} catch (ConnectException e) {
			log.error("ConnectException");
			e.printStackTrace();
		} catch (java.net.SocketTimeoutException e) {
			log.error("SocketTimeOutException");
			e.printStackTrace();
		} catch (IOException e) {
			log.error("IOException");
			e.printStackTrace();
		}

	}

}

====


2023-03-30 23:24:23.491] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:28 ]
INFO:Begin--001

2023-03-30 23:24:23.527] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:64 ]
INFO:Begin--002

2023-03-30 23:24:25.661] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:75 ]
INFO:-----STATUS CODE :----

2023-03-30 23:24:25.673] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:76 ]
INFO:200

2023-03-30 23:24:25.674] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:83 ]
INFO:----Response Head-----

2023-03-30 23:24:25.674] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:84 ]
INFO:value2

2023-03-30 23:24:25.674] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:86 ]
INFO:----Response Body-----

2023-03-30 23:24:25.674] [level: INFO] [Thread: main] [ Class:com.sxz.study.http.HttpClientTest >> Method: post:87 ]
INFO:{"status":"1","message":"张三---22---/C:/dev/workspace_202106/restFul/target/classes/"}
 

====

■更多代码(请求方,响应方)

java处理,调用外系统的 WebAPI(https请求)时,相关知识整理_java连接webapi_sun0322的博客-CSDN博客

====

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值