Это немного странно, и я сделал достаточно исследований, чтобы найти причину и решение этой проблемы. Моя цель - загрузить zip-файл с защищенного URL-адреса, который также требует входа в систему. Все работает отлично, когда я использую зависимость apache HTTPClient maven от версии 4.3.6. Тем не менее, я не могу использовать эту версию из-за того, что моя зависимость maven от aws-sdk-java-ядра также имеет зависимость httpclient и использование v4.3.6 заставляет aws-sdk-java жаловаться на исключение среды выполнения NoSuchMethod. Я понимаю эту проблему. Причина в том, что зависимость apache httpclient v4.3.6 более близка к дереву зависимостей maven, чем версия (4.5.1), используемая зависимостью aws-sdk-java-core. Во всяком случае, я сокращу более подробную информацию об этом, потому что я уверен, что я должен сделать все, чтобы работать с одной версией зависимости maven, а не использовать несколько версий одной и той же банки. Назад к оригинальному вопросу. Поскольку я не могу использовать v4.3.6, я сказал, что мой код использует v4.5.1, и это когда код загрузки файла начал давать проблемы. Когда я использую httpclient v4.5.1, ответ дает мне следующий html-контент, а не дает мне zip-файл, который у меня есть на запрошенном https-адресе.Загрузка zip-файла работает с apache httpclient v4.3.6, но сбой для другой версии
<html>
<HEAD><META HTTP-EQUIV='PRAGMA' CONTENT='NO-CACHE'><META HTTP-EQUIV='CACHE-
CONTROL' CONTENT='NO-CACHE'>
<TITLE>SAML 2.0 Auto-POST form</TITLE>
</HEAD>
<body onLoad="document.forms[0].submit()">
<NOSCRIPT>Your browser does not support JavaScript. Please click the
'Continue' button below to proceed. <br><br>
</NOSCRIPT>
<form action="https://githubext.deere.com/saml/consume" method="POST">
<input type="hidden" name="SAMLResponse" value="PFJlc3BvbnNlIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIERl">
<input type="hidden" name="RelayState" value="2F1HpzrUy5FdX">
<NOSCRIPT><INPUT TYPE="SUBMIT" VALUE="Continue"></NOSCRIPT>
</form>
</body>
</html>
Когда я использую v4.3.6, ответ дает мне почтовый файл как ожидаемый ответ. Я попытался вручную отправить этот html-контент, добавив больше кода, но ответ остается неповрежденным. Исходный код, который у меня есть для загрузки файла, приведен ниже.
@Component
public class FileDAO {
public static void main(String args[]) throws Exception{
new FileDAO().loadFile("https://some_url.domain.com/zipball/master","myfile.zip");
}
public String loadFile(String url, String fileName) throws ClientProtocolException, IOException {
HttpClient client = login();
HttpResponse response = client.execute(new HttpGet(url));
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
String unzipToFolderName = fileName.replace(".", "_");
FileOutputStream outputStream = new FileOutputStream(new File(fileName));
writeToFile(outputStream, response.getEntity().getContent());
return unzipToFolderName;
} else {
throw new RuntimeException("error downloading file, HTTP Status code: " + statusCode);
}
}
private void writeToFile(FileOutputStream outputStream, InputStream inputStream) {
try {
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (Exception ex) {
throw new RuntimeException("error writing zip file, error message : " + ex.getMessage(), ex);
} finally {
try {
outputStream.close();
inputStream.close();
} catch (Exception ex) {}
}
}
private HttpClient login() throws IOException {
HttpClient client = getHttpClient();
HttpResponse response = client.execute(new HttpGet("https://some_url.domain.com"));
String responseBody = EntityUtils.toString(response.getEntity());
Document doc = Jsoup.parse(responseBody);
org.jsoup.select.Elements inputs = doc.getElementsByTag("input");
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
HttpPost httpPost = new HttpPost("https://some_url.domain.com/saml/consume");
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("SAMLResponse", doc.select("input[name=SAMLResponse]").val()));
data.add(new BasicNameValuePair("RelayState", doc.select("input[name=RelayState]").val()));
httpPost.setEntity(new UrlEncodedFormEntity(data));
HttpResponse logingResponse = client.execute(httpPost);
int loginStatusCode = logingResponse.getStatusLine().getStatusCode();
if (loginStatusCode != 302) {
throw new RuntimeException("clone repo dao. error during login, HTTP Status code: " + loginStatusCode);
}
}
return client;
}
private HttpClient getHttpClient() {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("userId", "password");
provider.setCredentials(AuthScope.ANY, credentials);
return HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
}
}
Я все еще анализирую, что происходит с версиями apache httpclient, отличными от 4.3.6. Тот же код работает с 4.3.6, но не с версией выше 4.3.6. Любая помощь действительно оценена. Спасибо вам всем.