gpt4 book ai didi

java - zip 文件下载适用于 apache httpclient v4.3.6,但对于其他版本则失败

转载 作者:行者123 更新时间:2023-12-01 09:14:50 37 4
gpt4 key购买 nike

这有点奇怪,我已经做了足够多的研究来找到这个问题的原因和解决方案。我的目标是从也需要登录的安全 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 依赖项在 maven 依赖项树中比 aws-sdk-java-core 依赖项使用的版本 (4.5.1) 更接近。不管怎样,我会减少更多细节,因为我很确定我应该让所有东西都与一个版本的 Maven 依赖项一起工作,而不是使用同一个 jar 的多个版本。回到原来的问题。由于我无法使用 v4.3.6,我告诉我的代码使用 v4.5.1,这就是文件下载代码开始出现问题的时候。当我使用 httpclient v4.5.1 时,响应给我以下 html 内容,而不是给我请求的 https url 上的 zip 文件。

<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 时,响应为我提供了预期响应的 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 以外的 apache httpclient 版本出了什么问题。相同的代码适用于 4.3.6,但不适用于 4.3.6 以上的版本。非常感谢任何帮助。谢谢大家。

最佳答案

问题已解决。在仔细阅读 apache httpclient 文档并认真调试日志后,我可以解决这个问题。我必须创建两个服务器日志,一个用于 v4.3.6,另一个用于 v4.5.2。我开始比较服务器日志,发现罪魁祸首是cookie类型。旧版本中的 Cookie 类型(自动)配置为 BEST_MATCH 并且可以正常工作。然而,对于 v4.5.2,BEST_MATCH cookie 类型已从 apache 中弃用。添加更多代码后,我一直在尝试 cookie 设置,但服务器响应发送的 cookie 与我在客户端代码中配置的默认 cookie 类型不匹配。这导致 cookie 未正确设置,这就是响应返回 SAML 响应(再次登录页面)而不是 zip 文件的原因。

Apache cookie spec cookie 规范是这样说的:

默认:默认 cookie 策略是一种综合策略,它根据随 HTTP 响应发送的 cookie 的属性(例如版本属性,现在过时的)。在 HttpClient 的下一个次要版本中,将弃用此策略,转而采用标准(符合 RFC 6265)实现。标准严格:状态管理策略符合 RFC 6265 第 4 节定义的良好行为配置文件的语法和语义。

我将 Cookie 配置更新为 STANDARD_STRICT 模式,一切都开始在最新版本 4.5.2 上运行。

这是更新后的 getHttpClient() 方法:

private CloseableHttpClient getHttpClient() {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(gitUserId, gitPassword);
provider.setCredentials(AuthScope.ANY, credentials);
RequestConfig config = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
return HttpClientBuilder.create().setDefaultCredentialsProvider(provider).setDefaultRequestConfig(config).setRedirectStrategy(new LaxRedirectStrategy()).build();
}

关于java - zip 文件下载适用于 apache httpclient v4.3.6,但对于其他版本则失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40636201/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com