由于我们不知道是什么导致了您的神秘错误,我建议放弃第三方库,并使用 java.net 包:
public void readMembers(String schemeAndAuthority,
String username,
String password,
Path membersFileToWrite)
throws IOException {
URI baseURI = URI.create(schemeAndAuthority);
CookieHandler oldCookieHandler = CookieHandler.getDefault();
boolean oldFollowRedirects = HttpURLConnection.getFollowRedirects();
CookieHandler.setDefault(new CookieManager());
HttpURLConnection.setFollowRedirects(true);
try {
HttpURLConnection connection;
URI authURI = baseURI.resolve("/qm/authenticated/identity");
connection = (HttpURLConnection) authURI.toURL().openConnection();
connection.getResponseCode();
URI securityURI = baseURI.resolve(
"/qm/authenticated/j_security_check");
String postData =
"j_username=" + URLEncoder.encode(username, "UTF-8") + "&" +
"j_password=" + URLEncoder.encode(password, "UTF-8");
connection = (HttpURLConnection)
securityURI.toURL().openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setDoOutput(true);
try (OutputStream postBody = connection.getOutputStream()) {
postBody.write(postData.getBytes(StandardCharsets.UTF_8));
}
connection.getResponseCode();
URI catalogURI = baseURI.resolve(
"/qm/process/project-areas/_zzzzzzzzzzzzzzzzzzzz/members");
connection = (HttpURLConnection)
catalogURI.toURL().openConnection();
connection.setRequestProperty("Accept", "application/xml");
try (InputStream responseBody = connection.getInputStream()) {
Files.copy(responseBody, membersFileToWrite);
}
} finally {
CookieHandler.setDefault(oldCookieHandler);
HttpURLConnection.setFollowRedirects(oldFollowRedirects);
}
}
但是,上面的代码没有提供相当于 curl 的-k
选项。为此,我们必须创建一个自定义SSLContext ,使用允许所有证书的TrustManager进行初始化:
static class PermissiveTrustManager
extends X509ExtendedTrustManager {
private final X509ExtendedTrustManager[] realTrustManagers;
private interface Checker {
void checkWith(X509ExtendedTrustManager realTrustManager)
throws CertificateException;
}
PermissiveTrustManager() {
TrustManagerFactory factory;
try {
factory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
factory.init((KeyStore) null);
} catch (GeneralSecurityException e) {
// We should not be able to get here.
throw new RuntimeException(e);
}
TrustManager[] allTrustManagers = factory.getTrustManagers();
realTrustManagers = Arrays.stream(allTrustManagers)
.filter(tm -> tm instanceof X509ExtendedTrustManager)
.map(tm -> (X509ExtendedTrustManager) tm)
.toArray(X509ExtendedTrustManager[]::new);
}
private void check(Checker checker) {
try {
for (X509ExtendedTrustManager realTrustManager : realTrustManagers) {
checker.checkWith(realTrustManager);
}
} catch (CertificateException e) {
System.err.println("Ignoring invalid certificate");
e.printStackTrace();
}
}
private void check(Checker checker,
Socket socket) {
try {
for (X509ExtendedTrustManager realTrustManager : realTrustManagers) {
checker.checkWith(realTrustManager);
}
} catch (CertificateException e) {
System.err.println("Ignoring invalid certificate for " +
socket.getRemoteSocketAddress());
e.printStackTrace();
}
}
@Override
public void checkClientTrusted(X509Certificate[] certChain,
String authType,
Socket socket) {
check(tm -> tm.checkClientTrusted(certChain, authType, socket), socket);
}
@Override
public void checkClientTrusted(X509Certificate[] certChain,
String authType,
SSLEngine engine) {
check(tm -> tm.checkClientTrusted(certChain, authType, engine));
}
@Override
public void checkServerTrusted(X509Certificate[] certChain,
String authType,
Socket socket) {
check(tm -> tm.checkServerTrusted(certChain, authType, socket), socket);
}
@Override
public void checkServerTrusted(X509Certificate[] certChain,
String authType,
SSLEngine engine) {
check(tm -> tm.checkServerTrusted(certChain, authType, engine));
}
@Override
public void checkClientTrusted(X509Certificate[] certChain,
String authType) {
check(tm -> tm.checkClientTrusted(certChain, authType));
}
@Override
public void checkServerTrusted(X509Certificate[] certChain,
String authType) {
check(tm -> tm.checkServerTrusted(certChain, authType));
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
private static SSLContext createPermissiveSSLContext()
throws IOException {
TrustManager[] trustManagers = { new PermissiveTrustManager() };
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, null);
return context;
} catch (GeneralSecurityException e) {
throw new IOException(e);
}
}
public void readMembers(String schemeAndAuthority,
String username,
String password,
Path membersFileToWrite)
throws IOException {
URI baseURI = URI.create(schemeAndAuthority);
CookieHandler oldCookieHandler = CookieHandler.getDefault();
boolean oldFollowRedirects = HttpURLConnection.getFollowRedirects();
SSLContext oldSSLContext = null;
try {
oldSSLContext = SSLContext.getDefault();
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
CookieHandler.setDefault(new CookieManager());
HttpURLConnection.setFollowRedirects(true);
SSLContext.setDefault(createPermissiveSSLContext());
try {
HttpURLConnection connection;
URI authURI = baseURI.resolve("/qm/authenticated/identity");
connection = (HttpURLConnection) authURI.toURL().openConnection();
connection.getResponseCode();
URI securityURI = baseURI.resolve(
"/qm/authenticated/j_security_check");
String postData =
"j_username=" + URLEncoder.encode(username, "UTF-8") + "&" +
"j_password=" + URLEncoder.encode(password, "UTF-8");
connection = (HttpURLConnection)
securityURI.toURL().openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setDoOutput(true);
try (OutputStream postBody = connection.getOutputStream()) {
postBody.write(postData.getBytes(StandardCharsets.UTF_8));
}
connection.getResponseCode();
URI catalogURI = baseURI.resolve(
"/qm/process/project-areas/_zzzzzzzzzzzzzzzzzzzz/members");
connection = (HttpURLConnection)
catalogURI.toURL().openConnection();
connection.setRequestProperty("Accept", "application/xml");
try (InputStream responseBody = connection.getInputStream()) {
Files.copy(responseBody, membersFileToWrite);
}
} finally {
CookieHandler.setDefault(oldCookieHandler);
HttpURLConnection.setFollowRedirects(oldFollowRedirects);
if (oldSSLContext != null) {
SSLContext.setDefault(oldSSLContext);
}
}
}
显然,我没有办法对此进行测试。
您可以像这样调用该方法:
new CatalogRetriever().readMembers(
"https://zzzzzzz.zzzzz.zz.zz:9443", "myUN", "myPW",
Paths.get("members"));
如URI docs 中所述,该方案是http:
orhttps:
部分。权限//
后跟主机名/端口(以及可选的用户/密码,具体取决于协议)。