HttpURLConnection碰到连续302跳转的问题

本文探讨使用HttpURLConnection处理网页重定向的问题,特别是在遇到连续302跳转时出现连接重置异常的情况。通过对比分析,给出了使用Apache HttpClient替代方案的具体步骤及优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用HttpURLConnection联网的代码:

      HttpURLConnection conn = null;
      URL url = new URL("http://10.0.0.172/");
      conn = (HttpURLConnection) url.openConnection();

      conn .setRequestMethod("POST");
      conn .setDoInput(true);
      conn .setDoOutput(true);
      conn.setRequestProperty("X-Online-Host","www.xxxx.com");

      conn.setConnectTimeout(30000); // 30秒超时
      conn.connect();

 

如果返回的页面是一个302跳转,会自动跳转,但是如果跳转过去后还是一个302跳转,就卡在connect()这里了,超时之后一个 connection reset 的 exception. 不论Get还是Post方法,都一样问题。用setFollowRedirects关掉自动重定向,还是connection reset. 查了很长时间,还是弄不出个所以然来,看HttpURLConnection 的实现代码,redirect大于4次才会抛出一个Too many redirects 的异常,这才两个302就挂了...最后换用org.apache.http包里的东西,就没有问题。

 

  DefaultHttpClient httpClient = new DefaultHttpClient();

  HttpHost proxy = new HttpHost("10.0.0.172", 80);
  httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,proxy);
  HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),20 * 1000);
  HttpConnectionParams.setSoTimeout(httpClient.getParams(), 20 * 1000);
  HttpGet httpget = new HttpGet(theurl);
  HttpResponse response = httpClient.execute(httpget);

 

无论是自动跳转还是手动处理跳转都没有问题

在鸿蒙系统中处理 HTTP 302 重定向问题,主要涉及到网络请求的配置与处理逻辑。HTTP 302 状态码表示请求的资源暂时被移动到另一个位置,服务器会在响应头中返回 `Location` 字段,指示新的 URL 地址。浏览器或客户端在接收到 302 响应后,会自动向新的 URL 发起请求。在鸿蒙系统的开发中,可以通过以下方式进行处理: ### 1. 使用 `HttpURLConnection` 或 `OkHttp` 处理 302 重定向 鸿蒙系统支持使用 Java 或 JS 的网络请求库来处理 HTTP 请求。对于 302 重定向,可以通过禁用自动重定向功能,手动处理跳转逻辑。 #### 使用 `HttpURLConnection` 禁用自动重定向 ```java HttpURLConnection connection = (HttpURLConnection) new URL("https://example.com").openConnection(); connection.setInstanceFollowRedirects(false); // 禁用自动重定向 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP) { String newLocation = connection.getHeaderField("Location"); // 手动发起新的请求 HttpURLConnection newConnection = (HttpURLConnection) new URL(newLocation).openConnection(); // 继续处理新的请求 } ``` #### 使用 `OkHttp` 禁用自动重定向 ```java OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false) // 禁用自动重定向 .build(); Request request = new Request.Builder() .url("https://example.com") .build(); Response response = client.newCall(request).execute(); if (response.code() == 302) { String newLocation = response.header("Location"); // 手动发起新的请求 Request newRequest = new Request.Builder() .url(newLocation) .build(); Response newResponse = client.newCall(newRequest).execute(); // 处理新的响应 } ``` ### 2. 使用 `WebView` 处理 302 重定向 在鸿蒙系统中,如果需要通过 `WebView` 加载网页并处理 302 重定向,可以通过自定义 `WebViewClient` 来拦截重定向请求。 ```java webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 在这里处理重定向逻辑 if (url.contains("redirect")) { // 自定义处理逻辑 return true; // 表示已处理 } return super.shouldOverrideUrlLoading(view, url); } }); ``` ### 3. 使用 `Fetch` API 处理 302 重定向(JS 开发) 在鸿蒙的 JS 开发中,可以使用 `Fetch` API 发起网络请求,并通过 `redirect` 选项控制重定向行为。 ```javascript fetch('https://example.com', { method: 'GET', redirect: 'manual' // 手动处理重定向 }) .then(response => { if (response.status === 302) { const newLocation = response.headers.get('Location'); // 手动发起新的请求 return fetch(newLocation); } return response; }) .then(response => { // 处理响应 }) .catch(error => { // 处理错误 }); ``` ### 4. 服务器端配置优化 如果 302 重定向是由服务器端触发的,建议检查服务器配置,确保 `Location` 头字段的值正确无误。此外,可以通过服务器端设置 `Cache-Control` 或 `Expires` 头字段,减少不必要的重定向次数。 ### 5. 调试与日志 在处理 302 重定向时,建议启用网络请求的日志记录功能,以便跟踪请求和响应的详细信息。例如,在 `OkHttp` 中可以使用 `HttpLoggingInterceptor` 来记录日志。 ```java HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build(); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值