Lấy DataSource
triển khai
Thông thường, trình điều khiển JDBC
của bạn cung cấp triển khai javax.sql.DataSource
.
Để biết thêm chi tiết, hãy xem Câu trả lời của tôi cho một Câu hỏi tương tự.
PGSimpleDataSource
Nếu sử dụng trình điều khiển JDBC từ jdbc.postgresql.org
, bạn có thể sử dụng org.postgresql.ds.PGSimpleDataSource
lớp dưới dạng DataSource
của bạn thực hiện.
Khởi tạo một đối tượng thuộc loại PGSimpleDataSource
, sau đó gọi các phương thức setter để cung cấp tất cả thông tin cần thiết để kết nối với máy chủ cơ sở dữ liệu của bạn. Trang web trên trang DigitalOcean liệt kê tất cả các phần thông tin này cho trường hợp cơ sở dữ liệu cụ thể của bạn.
Về cơ bản thì thế này:
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" );
Tên máy chủ số nhiều và số cổng
Thật không may, phiên bản số ít của các phương thức setServerName
và setPortNumber
không được dùng nữa. Tuy khó chịu nhưng có lẽ chúng ta nên sử dụng phiên bản số nhiều của các phương thức đó (setServerNames
&setPortNumbers
) mà mỗi lấy một mảng. Chúng tôi điền vào một cặp mảng một phần tử, String[]
và int[]
, với địa chỉ máy chủ của chúng tôi và số cổng
sử dụng các ký tự mảng:
- {"your-server-address-go-here"}
- {your-port-number-go-here}
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" );
Mã hóa SSL / TLS
Cuối cùng, chúng tôi cần thêm thông tin cho mã hóa SSL / TLS được đề cập trong Câu hỏi.
Trớ trêu thay, không gọi setSsl( true )
Bạn sẽ nghĩ rằng chúng tôi sẽ gọi là setSsl
và chuyển true
. Nhưng không. Mặc dù phản trực quan nhưng việc đặt điều đó thành true sẽ khiến các nỗ lực kết nối của bạn không thành công. Tôi không biết tại sao lại như vậy. Nhưng thử-và-sai khiến tôi tránh cuộc gọi đó.
Chứng chỉ CA
Để ứng dụng Java phía máy khách của bạn bắt đầu kết nối SSL / TLS, trình điều khiển JDBC phải có quyền truy cập vào chứng chỉ CA được sử dụng bởi Digital Ocean. Trên trang quản trị Digital Ocean của bạn, nhấp vào Download CA certificate
liên kết để tải xuống một tệp văn bản nhỏ. Tệp đó sẽ được đặt tên là ca-certificate.crt
.
Chúng tôi cần cung cấp văn bản của tệp đó vào trình điều khiển JDBC của chúng tôi dưới dạng một chuỗi. Làm như sau để tải tệp thành chuỗi văn bản.
// 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." ); }
Chuyển văn bản chứng chỉ CA đó tới trình điều khiển JDBC của bạn bằng lệnh gọi tới DataSource::setSslCert
. Lưu ý rằng chúng tôi không gọi setSslRootCert
. Không trộn lẫn hai phương pháp có tên giống nhau.
dataSource.setSslCert( cert );
Kiểm tra kết nối
Cuối cùng, chúng ta có thể sử dụng DataSource
đã định cấu hình đối tượng để tạo kết nối với cơ sở dữ liệu. Mã đó sẽ giống như sau:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Hoàn thành mã mẫu
Tổng hợp tất cả những thứ đó lại với nhau, hãy xem một cái gì đó như thế này.
// 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();
}
Nguồn đáng tin cậy
Khi tạo phiên bản Postgres của bạn trên DigitalOcean.com, bạn sẽ được cung cấp khả năng hạn chế các yêu cầu kết nối đến. Bạn có thể chỉ định một địa chỉ IP duy nhất mà máy chủ Postgres mong đợi, một “nguồn đáng tin cậy” trong biệt ngữ của Digital Ocean. Bất kỳ tin tặc nào cố gắng kết nối với máy chủ Postgres của bạn sẽ bị bỏ qua vì chúng bắt nguồn từ các địa chỉ IP khác.
Mẹo:Nhấp vào bên trong trường nhập dữ liệu cho số địa chỉ IP này để trang web tự động phát hiện và cung cấp địa chỉ IP hiện đang được trình duyệt web của bạn sử dụng. Nếu bạn đang chạy mã Java của mình từ cùng một máy tính, hãy sử dụng cùng số IP đó làm nguồn tin cậy duy nhất của bạn.
Nếu không, hãy nhập địa chỉ IP của máy tính chạy mã Java JDBC của bạn.
Các vấn đề khác
Tôi chưa giải quyết các chi tiết, chẳng hạn như các giao thức bảo mật thích hợp để sử dụng để quản lý tệp chứng chỉ CA của bạn hoặc chẳng hạn như ngoại hóa thông tin kết nối của bạn bằng cách lấy DataSource
đối tượng từ JNDI
máy chủ thay vì mã hóa cứng
. Nhưng hy vọng các ví dụ trên sẽ giúp bạn bắt đầu.