これはちょっと変わったものですが、私はこの問題の原因と解決方法を見つけるのに十分な研究を行っています。私の目的は、ログインが必要なセキュリティ保護されたURLからzipファイルをダウンロードすることです。 バージョン4.3.6のapache httpClient maven依存関係を使用すると、すべてが完璧に動作します。しかし、私のaws-sdk-java-core-maven依存性にもhttpclient依存性があり、v4.3.6を使用するとaws-sdk-javaがNoSuchMethodランタイム例外について不平を言ってしまうため、このバージョンを使用することはできません。私はこの問題を理解しています。その理由は、Apacheのhttpclient v4.3.6の依存関係は、aws-sdk-java-core依存関係で使用されているバージョン(4.5.1)よりもmaven依存ツリーで最も近いためです。とにかく、これについてもっと詳しく説明します。なぜなら、すべてのものをmaven依存関係の1つのバージョンで動作させ、同じjarの複数のバージョンを使用しないようにする必要があるからです。 元の質問に戻るv4.3.6を使用できないので、v4.5.1を使用するようにコードに指示しました。私がhttpclient v4.5.1を使用すると、リクエストしたhttps urlにあるzipファイルを返すのではなく、次のHTMLコンテンツが返されます。zipファイルのダウンロードはapache httpclient v4.3.6で動作しますが、他のバージョンでは失敗します
私はv4.3.6を使用すると、応答が私に期待される応答としてzipファイルを与えます。私はコードを追加してこの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();
}
}
私はまだ4.3.6以外のバージョンのhttpclientで問題が起こっていると分析しています。同じコードは4.3.6で動作しますが、4.3.6より上のバージョンでは動作しません。 本当にありがとうございます。皆さん、ありがとうございました。