获得一个DataSource
执行
通常你的JDBC驱动程序 https://en.wikipedia.org/wiki/JDBC_driver提供了一个实现javax.sql.DataSource https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/javax/sql/DataSource.html.
有关更多详细信息,请参阅我的答案 https://stackoverflow.com/a/45091982/642706类似的问题。
PGSimpleDataSource
如果使用 JDBC 驱动程序jdbc.postgresql.org https://jdbc.postgresql.org,您可以使用org.postgresql.ds.PGSimpleDataSource https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/ds/PGSimpleDataSource.html类作为你的DataSource
执行。
实例化类型的对象PGSimpleDataSource
,然后调用 setter 方法来提供连接到数据库服务器所需的所有信息。 DigitalOcean 站点上的网页列出了您的特定数据库实例的所有这些信息。
基本上是这样的:
PGSimpleDataSource dataSource = new PGSimpleDataSource();
dataSource.setServerName( "your-server-address-goes-here" );
dataSource.setPortNumber( your-port-number-goes-here );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
复数服务器名称和端口号
不幸的是,这些方法的单一版本setServerName
and setPortNumber
已弃用。虽然很烦人,但我们应该使用这些方法的复数版本(setServerNames
& setPortNumbers
)每个都采用一个数组。我们填充一对单元素数组,String[]
and int[]
,以及我们服务器的地址和端口号 https://en.wikipedia.org/wiki/Port_(computer_networking)使用数组文字:
- {“您的服务器地址位于此处”}
- { 这里是您的端口号 }
PGSimpleDataSource dataSource = new PGSimpleDataSource();
String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
SSL/TLS 加密
最后,我们需要添加问题中解决的 SSL/TLS 加密的信息。
讽刺的是,做not call setSsl( true )
你可能会认为我们会调用setSsl https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/ds/common/BaseDataSource.html#setSsl-boolean-方法和通过true
。但不是。虽然违反直觉,但将其设置为 true 将导致您的连接尝试失败。我不知道这是为什么。但反复试验让我避免了这个决定。
CA证书
为了让您的客户端 Java 应用程序初始化 SSL/TLS 连接,JDBC 驱动程序必须有权访问CA证书由数字海洋使用。在您的 Digital Ocean 管理页面上,单击Download CA certificate
下载小文本文件的链接。该文件将被命名为ca-certificate.crt
.
我们需要将该文件的文本作为字符串提供给我们的 JDBC 驱动程序。执行以下操作将文件加载到文本字符串中。
// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
cert = Files.readString( path , StandardCharsets.UTF_8 );
System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }
通过调用将该 CA 证书文本传递给您的 JDBC 驱动程序DataSource::setSslCert https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/ds/common/BaseDataSource.html#setSslCert-java.lang.String-。请注意,我们是not呼叫setSslRootCert https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/ds/common/BaseDataSource.html#setSslRootCert-java.lang.String-。不要混淆这两个名称相似的方法。
dataSource.setSslCert( cert );
测试连接
最后我们就可以使用配置好的DataSource
对象来建立与数据库的连接。该代码将如下所示:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
完整的示例代码
把所有这些放在一起,看到这样的东西。
// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
cert = Files.readString( path , StandardCharsets.UTF_8 );
System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }
// PGSimpleDataSource configuration
PGSimpleDataSource dataSource = new PGSimpleDataSource();
String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setSslCert( cert );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
可信来源
在 DigitalOcean.com 上创建 Postgres 实例时,您将能够限制传入的连接请求。您可以指定 Postgres 服务器所需的单个 IP 地址,这是 Digital Ocean 行话中的“可信源”。任何尝试连接到您的 Postgres 服务器的黑客都将被忽略,因为它们来自其他 IP 地址。
提示:在该 IP 地址号码的数据输入字段内单击,让网页自动检测并提供您的网络浏览器当前使用的 IP 地址。如果您从同一台计算机运行 Java 代码,请使用相同的 IP 号码作为您的单一可信源。
否则,请输入运行 Java JDBC 代码的计算机的 IP 地址。
其他事宜
我还没有详细阐述,例如用于管理 CA 证书文件的适当安全协议,或者通过获取DataSource
对象从一个JNDI https://en.wikipedia.org/wiki/Java_Naming_and_Directory_Interface服务器而不是硬编码 https://en.wikipedia.org/wiki/Hard_coding。但希望上面的示例可以帮助您入门。