Java sdk连接fabric网络的谜之报错

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Java sdk连接fabric网络的谜之报错

谜之报错

下面是一个使用fabric-java-sdk和fabric-java-gateway尝试连接上述虚拟机的未解决的一堆报错。更离谱的是,每一次报错都还不一样。。。

由于这是一个未解决的连接错误,我只阐述我做了什么和得到的反馈,也希望有类似经历的伙伴提供一些建议。

connection.json配置文件

{
  "name": "basic-network",
  "version": "1.0.0",
  "dependencies": {
  },
  "client": {
    "organization": "Department1",
    "connection": {
      "timeout": {
        "peer": {
          "endorser": "30000"
        },
        "orderer": "30000"
      }
    },
    "organization": "Department2",
    "connection": {
      "timeout": {
        "peer": {
          "endorser": "30000"
        },
        "orderer": "30000"
      }
    }
  },
  "channels": {
    "tracechannel": {
      "orderers": [
        "orderer.trace.com"
      ],
      "peers": {
        "peer0.department1.trace.com": {
          "endorsingPeer": true,
          "chaincodeQuery": true,
          "ledgerQuery": true,
          "eventSource": true
        },
        "peer0.department2.trace.com": {
          "endorsingPeer": true,
          "chaincodeQuery": true,
          "ledgerQuery": true,
          "eventSource": true
        },
      }
    }
  },
  "organizations": {
    "Department1": {
      "mspid": "Department1MSP",
      "peers": [
        "peer0.department1.trace.com",
      ],
      "adminPrivateKeyPEM": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department1.trace.com/users/Admin@department1.trace.com/msp/keystore/priv_sk"
      },
      "signedCertPEM": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department1.trace.com/users/Admin@department1.trace.com/msp/signcerts/Admin@department1.trace.com-cert.pem"
      }
    },
    "Department2": {
      "mspid": "Department2MSP",
      "peers": [
        "peer0.department2.trace.com",
      ],
      "adminPrivateKeyPEM": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department2.trace.com/users/Admin@department2.trace.com/msp/keystore/priv_sk"
      },
      "signedCertPEM": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department2.trace.com/users/Admin@department2.trace.com/msp/signcerts/Admin@department2.trace.com-cert.pem"
      }
    }
  },
      "mspid": "OrdererMSP",
      "grpcOptions": {"orderers": {
        "orderer.trace.com": {
          "url": "grpcs://127.0.0.1:7050",
        "ssl-target-name-override": "orderer.trace.com",
        "hostnameOverride": "orderer.trace.com"
      },
      "tlsCACerts": {
        "path": "src/main/resources/crypto-config/ordererOrganizations/trace.com/orderers/orderer.trace.com/tls/ca.crt"
      },
      "adminPrivateKeyPEM": {
        "path": "src/main/resources/crypto-config/ordererOrganizations/trace.com/users/Admin@trace.com/msp/keystore/priv_sk"
      },
      "signedCertPEM": {
        "path": "src/main/resources/crypto-config/ordererOrganizations/trace.com/users/Admin@trace.com/msp/signcerts/Admin@trace.com-cert.pem"
      }
    }
  },
  "peers": {
    "peer0.department1.trace.com": {
      "url": "grpcs://127.0.0.1:7051",
      "grpcOptions": {
        "ssl-target-name-override": "peer0.department1.trace.com",
        "hostnameOverride": "peer0.department1.trace.com",
        "request-timeout": 120001
      },
      "tlsCACerts": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department1.trace.com/peers/peer0.department1.trace.com/tls/ca.crt"
      }
    },
    "peer0.department2.trace.com": {
      "url": "grpcs://127.0.0.1:8051",
      "grpcOptions": {
        "ssl-target-name-override": "peer0.department2.trace.com",
        "hostnameOverride": "peer0.department2.trace.com",
        "request-timeout": 120001
      },
      "tlsCACerts": {
        "path": "src/main/resources/crypto-config/peerOrganizations/department2.trace.com/peers/peer0.department2.trace.com/tls/ca.crt"
      }
    },
  }
}

官方案例测试Sample.java

package com.zcongfly;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.hyperledger.fabric.gateway.*;
import org.hyperledger.fabric.gateway.impl.GatewayImpl;
import org.hyperledger.fabric.sdk.HFClient;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
 * @author admin
 */
public class Sample {
    private Gateway gateway;
    private Network network;
    private static final Path NETWORK_CONFIG_PATH = Paths.get("src","main", "resources", "connection.json");
    private static final Path credentialPath = Paths.get("src","main","resources", "crypto-config", "peerOrganizations", "department1.trace.com", "users", "User1@department1.trace.com", "msp");
    public static void main(String[] args) throws IOException {
        X509Certificate certificate = null;
        PrivateKey privateKey = null;
        Gateway gateway = null;
        try {
            //使用org1中的user1初始化一个网关wallet账户用于连接网络
            Wallet wallet = Wallets.newInMemoryWallet();
            Path certificatePath = credentialPath.resolve(Paths.get("signcerts", "User1@department1.trace.com-cert.pem"));
            certificate = readX509Certificate(certificatePath);
            Path privateKeyPath = credentialPath.resolve(Paths.get("keystore", "priv_sk"));
            privateKey = getPrivateKey(privateKeyPath);
            wallet.put("user",Identities.newX509Identity("Department1MSP",certificate,privateKey));
            //根据connection.json 获取Fabric网络连接对象
            GatewayImpl.Builder builder = (GatewayImpl.Builder) Gateway.createBuilder();
            builder.identity(wallet, "user").networkConfig(NETWORK_CONFIG_PATH);
            //连接网关
            gateway = builder.connect();
            System.out.println("=====================已连接到网关!=======================");
            //获取mychannel通道
            Network network = gateway.getNetwork("mychannel");
            System.out.println(network);
            System.out.println("===================已连接到指定通道!========================================");
            //获取合约对象
            Contract myoilcc = network.getContract("myoilcc");
            System.out.println(myoilcc);
            // 提交事务 存储到账本
            //byte[] createSaccResult = myprovocoilContract.createTransaction("addoilaccount").submit("3","2022.04.21","136.0","3","1","","36");
            //System.out.println("myprovocoil油料存储:" + new String(createSaccResult, StandardCharsets.UTF_8));
            // 查询
            //byte[] queSaccResult = myprovocoilContract.createTransaction("query").submit("001油品");
            //System.out.println("myprovocoil油料查询结果:" + new String(queSaccResult, StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 从文件或流中读取X.509证书并返回一个X509Certificate对象。
     *X.509证书是一种数字证书格式,常用于加密、签名和身份验证等安全应用程序中。
     * 在Hyperledger Fabric中,X.509证书也被广泛用于身份验证和授权。
     * 使用Java编写的Hyperledger Fabric客户端应用程序通常需要读取和解析X.509证书以进行身份验证和交易提交。
     * readX509Certificate方法接受一个InputStream参数,该参数指定了包含X.509证书数据的输入流。
     * 该方法首先创建一个CertificateFactory实例,并使用该实例从输入流中加载证书数据并返回一个X509Certificate对象。
     */
    private static X509Certificate readX509Certificate(final Path certificatePath) throws IOException, CertificateException {
        try (Reader certificateReader =
                     Files.newBufferedReader(certificatePath, StandardCharsets.UTF_8)) {
            return Identities.readX509Certificate(certificateReader);
        }
    }
    /**
     * 从文件或流中读取私钥数据并返回一个PrivateKey对象。
     * 在Hyperledger Fabric中,使用X.509证书进行身份验证和授权时,通常需要提供与证书关联的私钥。
     * 使用Java编写的Hyperledger Fabric客户端应用程序通常需要读取和解析私钥以进行身份验证和交易提交。
     * getPrivateKey方法接受两个参数,分别是包含私钥数据的InputStream对象和私钥的密码。
     * 该方法首先创建一个KeyStore实例,并使用该实例从输入流中加载私钥数据和相关证书链。
     * 然后,该方法使用密码解密私钥数据,并返回一个PrivateKey对象。
     */
    private static PrivateKey getPrivateKey(final Path privateKeyPath) throws IOException, InvalidKeyException {
        try (Reader privateKeyReader =
                     Files.newBufferedReader(privateKeyPath, StandardCharsets.UTF_8)) {
            return Identities.readPrivateKey(privateKeyReader);
        }
    }
}

报错1:

虚拟机使用的是NAT模式,已开启ssh服务,并在虚拟机上设置了端口转发,将22端口映射成主机上的2222端口,目前主机可以通过ssh命令连接到虚拟机,命令是ssh username@127.0.0.1 -p 2222,但是再使用fabric-java-sdk连接连接到该虚拟机上启动的fabric网络时一直报错,目前主机仍然无法ping通虚拟机的ip地址,只能通过ssh username@127.0.0.1 -p 2222命令与虚拟机进行连接和通信。

以下是connection.json的当前配置:

"orderers": {
    "orderer.trace.com": {
      "url": "grpcs://localhost:7050",

不论将url改成127.0.0.1、localhost、虚拟机ip、虚拟机内部IP均报错Connection refused

ERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: 7d61cbf1e1cbdab5a17d552254cd5957bbd19006813169c2c6031e90dfd384ae to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://localhost:8051, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=io exception, cause=io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/[0:0:0:0:0:0:0:1]:8051
Caused by: java.net.ConnectException: Connection refused: no further information

将url改为grpcs://localhost:2222,报错Connection refused

ERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: ca2ff093f2624894dc15a90ef9f7f497d5510fad9e3e29663a143b1609007447 to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://localhost:2222, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=io exception, cause=io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/[0:0:0:0:0:0:0:1]:2222
Caused by: java.net.ConnectException: Connection refused: no further information

这应该属于同一类错误。

报错2:

查阅资料,启用ssh隧道:

ssh -L 5000:localhost:5000 zcongfly@127.0.0.1 -p 2222

修改所有节点的grpc的url为:

"url": "grpcs://localhost:5000",

报错变成了Connection reset

ERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: d98f80a464b5011fa2cbee88d74a6ce8bcab09c39244bb0670ccabd2325b9347 to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://127.0.0.1:5000, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0], cause=java.net.SocketException: Connection reset

报错3:

进一步查阅资料:

https://stackoverflow.com/questions/62897216/why-am-i-getting-tls-handshake-error-when-i-try-to-connect-from-hyperledger-java

https://stackoverflow.com/questions/53625506/hyperledger-fabric-java-sdk-use-grpcs-for-peer-and-orderer-connections/53676602?r=SearchResults&s=2%7C14.4806#53676602

在crypto-config.ymal中添加SANS:

SANS:
  - "localhost"

在Java工程的src/main/resources文件夹下以管理员身份运行cmd,输入命令:

# 添加证书到java的jvm密钥库中
keytool -import -file crypto-config\peerOrganizations\department2.trace.com\peers\peer0.department2.trace.com\tls\server.crt -alias peer0.department2.trace.com -keystore "C:\Program Files\Java\jre1.8.0_281\lib\security\cacerts" -storepass changeit
keytool -import -file crypto-config\peerOrganizations\department1.trace.com\peers\peer0.department1.trace.com\tls\server.crt -alias peer0.department1.trace.com -keystore "C:\Program Files\Java\jre1.8.0_281\lib\security\cacerts" -storepass changeit
keytool -import -file crypto-config\ordererOrganizations\trace.com\orderers\orderer.trace.com\tls\server.crt -alias orderer.trace.com -keystore "C:\Program Files\Java\jre1.8.0_281\lib\security\cacerts" -storepass changeit

再次运行Sample.java,报错你的主机中的软件中止了一个已建立的连接

ERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: 9f9972c50afe9e23dd8ba4a9ca1cb9d81ec950b53bcc51d75991adf601b66964 to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://127.0.0.1:5000, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0], cause=java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

这个错误在网上倒也能找到些东西,也是Java连接远程数据库啥的。大致就是有可能虚拟机那边响应慢,sdk发送ssl连接请求时没等响应就断开或者发了一个新的请求,把连接中断了;或者是设置了timeout,超时就直接给断开了连接;又或者是短时间内重复提交了同一个表单导致连接中断,总之,都不是我这类情况。

参考:https://blog.csdn.net/qq_54070103/article/details/127441068

https://www.bbsmax.com/A/qVdepjbr5P/

此时,每运行一次Simple.java,cmd窗口中开始不断显示channel 3: open failed: connect failed: Connection refused

C:\WINDOWS\system32>ssh -L 7050:localhost:7050 zcongfly@127.0.0.1 -p 2222
zcongfly@127.0.0.1's password:
Last login: Fri Mar 31 08:15:03 2023 from gateway
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused
[zcongfly@localhost ~]$ channel 3: open failed: connect failed: Connection refused

这一度带给过我希望,是不是只要解决了信任问题就可以连接上了。

报错4:

求助于chat-gpt:

“如果您使用SSH端口转发将CentOS虚拟机上的peer节点端口映射到本地主机上的端口,则您可以在url中指定本地主机上的端口。在这种情况下,您应该将localhost设置为本地主机的IP地址(通常为127.0.0.1),并将端口设置为您在SSH端口转发命令中指定的本地端口(默认为2222)。

例如,如果您在本地主机上执行了以下SSH端口转发命令:

ssh -L 2222:localhost:7051 user@192.168.1.100

则您的url应该类似于:

"url": "grpc://127.0.0.1:2222"

这将允许Java SDK客户端通过本地主机上的端口2222连接到CentOS虚拟机上的peer节点的GRPC服务。”

如果要连接多个peer节点该如何操作呢?比如连接到peer0的7051端口、peer1的8051端口、peer2的9051端口?

如果要连接多个peer节点,您需要为每个peer节点执行SSH端口转发命令,并将它们映射到本地主机的不同端口。例如:

ssh -L 2222:localhost:7051 user@192.168.1.100
ssh -L 3333:localhost:8051 user@192.168.1.100
ssh -L 4444:localhost:9051 user@192.168.1.100

以上命令将分别将CentOS虚拟机上peer0、peer1和peer2的GRPC服务端口映射到本地端口2222、3333和4444上。

接下来,您可以在Java SDK客户端中使用以下代码来连接这些peer节点:

List<Peer> peers = new ArrayList<>();
peers.add(HFClient.createNewDefaultPeer("peer0", "grpc://127.0.0.1:2222"));
peers.add(HFClient.createNewDefaultPeer("peer1", "grpc://127.0.0.1:3333"));
peers.add(HFClient.createNewDefaultPeer("peer2", "grpc://127.0.0.1:4444"));
Channel channel = HFClient.createNewChannel("mychannel", orderer, config);
channel.addPeers(peers);

以上代码创建了一个包含所有peer节点的peers列表,并将其添加到一个名为mychannel的通道中。请注意,在每个grpc:// URL中,您需要指定正确的本地端口,以便连接到相应的peer节点。

这样,您就可以通过Java SDK客户端连接到多个peer节点的GRPC服务了。

先到虚拟机中在添加3333和4444的端口转发,然后以管理员身份启用3个cmd窗口,分别输入:

ssh -L 7050:localhost:7050 zcongfly@127.0.0.1 -p 2222
ssh -L 7051:localhost:7051 zcongfly@127.0.0.1 -p 3333
ssh -L 8051:localhost:8051 zcongfly@127.0.0.1 -p 4444

建立起3个ssh隧道并成功连接上之后,修改connection.json文件中各个节点url分别为:

"url": "grpcs://localhost:7050"
"url": "grpcs://localhost:7051"
"url": "grpcs://localhost:8051"

运行Sample.java,报错Connection closed while performing TLS negotiation

ERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: d2915393c441925665cb31c87a9c1803c0022707b124e35f27e72c20e762fedd to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://127.0.0.1:8051, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=Connection closed while performing TLS negotiation
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0], cause=java.nio.channels.ClosedChannelExceptionERROR org.hyperledger.fabric.sdk.Channel - Channel Channel{id: 1, name: mychannel} Sending proposal with transaction: d2915393c441925665cb31c87a9c1803c0022707b124e35f27e72c20e762fedd to Peer{ id: 2, name: peer0.department2.trace.com, channelName: mychannel, url: grpcs://127.0.0.1:8051, mspid: Department2MSP} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=Connection closed while performing TLS negotiation

这回变为TSL证书错误了。。。

这个错误表明在与peer节点进行TLS协商期间,连接已经被关闭,导致无法发送建议。这通常表示由于某些网络问题或配置错误而无法建立稳定的TLS连接。

您可以尝试检查以下几点:

  1. 确认您的peer节点是否正确启动并正在运行。您可以使用peer node status命令来检查。
  2. 检查peer节点的TLS证书和密钥是否正确生成,并且Java SDK客户端是否正确加载了这些证书和密钥。您可以检查SDK客户端的TLS设置,并确保它们与peer节点的TLS设置匹配。
  3. 检查您的网络环境,确保从Java SDK客户端到peer节点的网络连接是可用的,并且没有任何防火墙或网络代理阻止了通信。

如果您仍然无法解决问题,请尝试将日志级别设置为更高的水平,并检查详细的日志信息,以便更好地理解问题所在。

要检查Java SDK客户端中使用的TLS配置和证书,您可以检查以下内容:

  1. 客户端配置文件:检查您在创建SDK客户端时传递的配置文件。如果您使用了默认配置,该文件应为connection-profile.yaml
  2. TLS证书和密钥:检查配置文件中包含的TLS证书和密钥路径是否正确,并确保这些证书和密钥与peer节点的TLS设置匹配。
  3. TLS设置:检查配置文件中的TLS设置,例如是否启用了TLS,是否使用了正确的加密算法等。确保客户端的TLS设置与peer节点的TLS设置匹配。
  4. 日志输出:启用更详细的日志输出,以便检查TLS握手期间发生的任何错误或异常情况。您可以通过在SDK客户端代码中调用Logger.getLogger("org.hyperledger.fabric").setLevel(Level.DEBUG)来设置更高的日志级别。这将打印出更多的详细信息,包括TLS握手期间发生的事件和错误。
  5. 测试工具:您可以使用OpenSSL等工具测试从SDK客户端到peer节点的TLS连接是否正常工作。例如,您可以使用以下命令来测试与peer节点的TLS连接:
openssl s_client -connect <peer-hostname>:<peer-port> -tls1_2

以上命令将使用TLS 1.2连接到指定的peer节点,并打印出与TLS握手相关的详细信息。如果该命令能够成功连接到peer节点并打印出TLS握手信息,则可以确认TLS配置和证书设置正确。

(一下午了,Java也好fabric也罢,求求你们做个人吧。。。)

TSL一下触及到知识盲区了,其实前边的ssh和什么ssl连接的Java密钥就已经是盲区了。

先记录下,让我歇会儿。

目录
相关文章
|
6月前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
140 11
|
3月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
143 23
|
4月前
|
消息中间件 存储 NoSQL
java连接redis和基础操作命令
通过以上内容,您可以掌握在Java中连接Redis以及进行基础操作的基本方法,进而在实际项目中灵活应用。
210 30
|
4月前
|
安全 网络协议 Java
Java网络编程封装
Java网络编程封装原理旨在隐藏底层通信细节,提供简洁、安全的高层接口。通过简化开发、提高安全性和增强可维护性,封装使开发者能更高效地进行网络应用开发。常见的封装层次包括套接字层(如Socket和ServerSocket类),以及更高层次的HTTP请求封装(如RestTemplate)。示例代码展示了如何使用RestTemplate简化HTTP请求的发送与处理,确保代码清晰易维护。
|
5月前
|
Java Linux 数据库
java连接kerberos用户认证
java连接kerberos用户认证
145 22
|
4月前
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
142 0
|
5月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
202 2
|
7月前
|
数据采集 Java API
java怎么设置代理ip:简单步骤,实现高效网络请求
本文介绍了在Java中设置代理IP的方法,包括使用系统属性设置HTTP和HTTPS代理、在URL连接中设置代理、设置身份验证代理,以及使用第三方库如Apache HttpClient进行更复杂的代理配置。这些方法有助于提高网络请求的安全性和灵活性。
299 0
|
开发框架 .NET 区块链
Hyperledger fabric部署链码(五)初始化与链码升级
fabric部署chaincode-go(智能合约)系列之五
299 0
|
测试技术 Go 区块链
Hyperledger fabric 测试环境部署
Hyperledger fabric 测试环境部署及相关问题解答
442 3
Hyperledger fabric 测试环境部署

热门文章

最新文章