天天看点

java处理,调用外系统的 WebAPI(https请求)时,相关知识整理■整理内容■TODO

目录

■整理内容

1.外系统连接时,注意点

2.https证书相关问题---java---证书产生的错误---不被信任的证书

3.https证书相关问题---CURL---通过参数-可以忽略-证书信任问题

4.证书添加---在调用方-添加被调用方(WebAPI https)的证书

5.之前的一个作业,使用SFDC的WebAPI

6.HttpClient和RestTemplate的使用(详细对比)

7.SOAP通信

发送请求

解析

8.客户端证书与服务器证书

客户端证书与服务器证书有什么区别

客户端证书

9.客户端和服务器端的双向认证---客户端证明书(安装,指定)

1.浏览器安装

2.curl命令中指定

3.HttpClients代码中指定

■TODO

======

■整理内容

1.外系统连接时,注意点

与外系统连接时,需要考虑的问题_sun0322的博客-CSDN博客

2.https证书相关问题---java---证书产生的错误---不被信任的证书

HttpClient 使用时,出现「no trusted certificate found」的原因 (JDK没有安装相应的证明书)_sun0322的博客-CSDN博客_no trusted certificate found

3.https证书相关问题---CURL---通过参数-可以忽略-证书信任问题

使用JDK中的 keytool【创建证书】・【查看】・【使用】_sun0322的博客-CSDN博客_keytool查看证书信息

  └使用CURL命令访问https的网站

curl https://10.10.10.193/hello
           

如何不是信任机构发布的证书,会出现下面错误

curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - 证书链是由不受信任的颁发机构颁发的。

More details here: https://curl.se/docs/sslcerts.html

虽然,CURL中,使用参数k可以解决这个问题,

// F:Form         模拟用户在浏览器上点击“submit”按钮提交表单的操作。 比如,要提交存储密码的文件到服务器上,命令为:curl -F [email protected]/etc/passwd

// k:               接受服务器的ssl证书而不管合不合法。参数“-k”等同于“--insecure”。

// v:verbose     显示一次 http 通信的整个过程,包括端口连接和 http request 头信息。

但是,java的HttpClient和RestTemplate中,会出现认证的问题。「no trusted certificate found」

4.证书添加---在调用方-添加被调用方(WebAPI https)的证书

使用JDK中的 keytool【创建证书】・【查看】・【使用】_sun0322的博客-CSDN博客_keytool查看证书信息

└■扩展02.JDK添加证书的信任机构

加入JDK证书信任,C:\Program Files\Java\jre1.8.0_191\lib\security>目录下运行命令:

keytool -import -alias yourCacertName -keystore cacerts -file 盘:目录/证书文件.crt

keystore的默认密码“changeit”

===

5.之前的一个作业,使用SFDC的WebAPI

外部系统连接SFDC,获取SFDC侧的数据_sun0322的博客-CSDN博客

6.HttpClient和RestTemplate的使用(详细对比)

HttpClient和RestTemplate的使用(详细对比)_霞之秋诗羽的博客-CSDN博客_httpclient resttemplate

7.SOAP通信

Simple Object Access Protocol

简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。

===

发送请求

SOAP XML发送请求及解析返回的XML_普罗旺斯_S的博客-CSDN博客_soap xml

package com.common;

import org.apache.http.HttpEntity;
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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import javax.xml.soap.*;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

/**
 * Soap工具类
 *
 * @author XianYao
 * @version V1.0.0
 * @date 2022/3/8 15:40
 */
public class SoapUtil {
    public static void main(String[] args) {
        String xmlStr = "<Service>" +
                "<RegionCode>991</RegionCode>" +
                "<Word>嘉华园</Word>" +
                "<AccType></AccType>" +
                "<PageSize>10</PageSize>" +
                "<PageIndex>1</PageIndex>" +
                "</Service>";
        //webService接口地址
        String postUrl = "http://123.456.789:1234/ResWebservice/services/NewAddrService";
        //"http://tempuri.org/execute";
        String soapAction = "";
        //访问接口
        String result = SoapUtil.SplicingMessage(xmlStr, postUrl, soapAction, "searchAddr", "ns1:searchAddrResponse", "searchAddrReturn");
        System.out.println("返回的数据为:" + result);
    }

    /**
     * 访问webservice接口
     *
     * @param postUrl    webService接口地址
     * @param soapAction soapAction地址
     * @param method     方法名
     * @param node       节点
     * @param childNode  子节点
     * @return 返回值
     */
    public static String SplicingMessage(String xmlBodyStr, String postUrl, String soapAction, String method, String node, String childNode) {
        //自定义soap报文模板
        String xmlStr = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:addr=\"http://addr.webservice.ztesoft.com\">" +
                "   <soapenv:Header/>" +
                "   <soapenv:Body>" +
                "      <addr:" + method + " soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
                "         <xml xsi:type=\"xsd:string\">" +
                "          <![CDATA[" + xmlBodyStr + "]]>" +
                "         </xml>" +
                "      </addr:" + method + ">" +
                "   </soapenv:Body>" +
                "</soapenv:Envelope>";

        System.out.println("自定义soap报文模板 ===> " + xmlStr);
        return doPostSoap(postUrl, xmlStr, soapAction, node, childNode);
    }

    /**
     * 使用SOAP发送消息
     *
     * @param postUrl    webService接口地址
     * @param soapXml    请求体
     * @param soapAction soapAction
     */
    public static String doPostSoap(String postUrl, String soapXml, String soapAction, String node, String childNode) {
        String retStr = "";
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(postUrl);
        // 设置请求和传输超时时间
        RequestConfig requestConfig = RequestConfig.custom().build();
        httpPost.setConfig(requestConfig);
        try {
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
            httpPost.setHeader("SOAPAction", soapAction);
            StringEntity data = new StringEntity(soapXml, StandardCharsets.UTF_8);
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                retStr = EntityUtils.toString(httpEntity);
                System.out.println("soap响应内容 ===> " + retStr);
            }
            // 释放资源
            closeableHttpClient.close();
        } catch (Exception e) {
            
        }
        return soapXmlToBean(retStr, node, childNode);
    }

    /**
     * @param soapXml 请求结果string
     * @return 请求结果
     */
    public static String soapXmlToBean(String soapXml, String node, String childNode) {
        Iterator<SOAPElement> iterator = null;
        String res = "";
        try {
            //javax.xml.soap类MessageFactory
            MessageFactory msgFactory = MessageFactory.newInstance();
            //创建一个soapMessage对象
            SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(),
                    new ByteArrayInputStream(soapXml.getBytes(StandardCharsets.UTF_8)));
            reqMsg.saveChanges();
            //取出soapBody对象
            SOAPBody body = reqMsg.getSOAPBody();
            //遍历子节点
            iterator = body.getChildElements();
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (iterator.hasNext()) {
            SOAPElement element = iterator.next();
            System.out.println("节点名称---:" + element.getNodeName());
            if (node.equals(element.getNodeName())) {
                Iterator<SOAPElement> it = element.getChildElements();
                SOAPElement el = null;
                while (it.hasNext()) {
                    el = it.next();
                    //取到content子节点的值
                    if (childNode.equals(el.getNodeName())) {
                        System.out.println("子节点值---:" + el.getValue());
                        res = el.getValue();
                        break;
                    }
                }
                break;
            }
        }
        return res;
    }
}



           

===

解析

Java 发送和解析Soap Xml数据_青冘的博客-CSDN博客_soap xml 解析

==

8.客户端证书与服务器证书

客户端证书与服务器证书有什么区别

客户端证书与服务器证书有什么区别?_CauchyBDS的博客-CSDN博客_客户端证书

加密在传输过程中保护数据

服务器或SSL证书与客户端证书的角色非常相似,但后者用于标识客户端/个人,前者用于验证站点的所有者。服务器证书通常发布到主机名,主机名可以是计算机名称(例如“XYZ-SERVER-01”)或域名(例如“www.csdn.com”)。到达服务器的Web浏览器,并验证SSL服务器证书是否可信。这告诉用户他们与网站的互动没有窃听者,并且网站正是它声称的那个人。这种安全性对于电子商务至关重要,这就是证书现在如此广泛使用的原因。

他们是怎么做到的?实际上,网站运营商通过向证书提供者申请证书签名请求来获得证书。这是一份包含所有基本信息的电子文档:网站名称,联系电子邮件地址和公司信息。证书提供者签署请求,生成公共证书,该证书被提供给连接到网站的任何Web浏览器,并且关键地向Web浏览器证明提供者向他认为是其所有者的人颁发证书。网站。但是,在颁发证书之前,证书提供商将从公共域名注册商处请求该网站的联系电子邮件地址,并根据证书申请中提供的电子邮件地址检查该已发布的地址,

此外,您可以配置网站,以便任何希望连接的用户都需要提供有效的客户端证书以及有效的用户名和密码。这通常被称为“双因素身份验证” - 在这种情况下,“你知道的东西”(密码)和“你拥有的东西”(证书)。

客户端证书

ssh-keygen(linux 命令) 创建 private key(私钥) , public key (公钥),实现ssh,scp,sftp命令无密码连接_sshkeygen生成公钥私钥_sun0322的博客-CSDN博客

└5.客户端证书     (和【 https 网站 的 CA证书】, 分别是 两个 证书。)

9.客户端和服务器端的双向认证---客户端证明书(安装,指定)

1.浏览器安装

  略

2.curl命令中指定

curl --cert client.crt  --key client.key --insecure https://此处添加自己的网址及端口
           

3.HttpClients代码中指定

https://www.cnblogs.com/jiaoyiping/p/5469660.html

■TODO

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

业务:

①A系统  ⇒ B系统    ⇒ C系统    ⇒ 本系统(insert/update API) ⇒ B系统 (API https)⇒ (insert/update)B系统中 【XXX 数据库】

②X系统  ⇒ B系统    ⇒ C系统    ⇒ 本系统 

按照要件,C系统  不做任何修改

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

1.B系统、有(权威机构认证的)证书?

               没有的话,B系统的证明书,是否已经导入到(本系统的)JDK的cacerts 中?

2.saop,json混在?

            ⇒ 根据 B系统 API 的 I/F 不使用SOAP,使用JSON

3.暗号化  有无已有代码

4.①里面真的需要update吗?

             如果需要, 在那个系统里面,什么时点调用?

5.B系统   提供了 insert  I/F 接口。

            但是,按照现在的要件,B系统 并没有 提供  update I/F 接口 !!!

6.如何确认是 ① 这条流来的数据

   (!!!注意:按照要件,C系统  不做任何修改)

    (重点确认,能否根据,传递到 本系统(insert/update API) 的某个字段,来确认是: ① 这条流来的数据。  )

7.HttpClient和RestTemplate使用哪一个。(看看POM是否有已经引用的jar)

8.【XXX 数据库】和 【 A系统 】 有什么关系,看起来并不是一个系统。

===========