Android Volley BasicNetwork:performRequest:Unexpected response code 302 for http://xxx异常,这个http://xxx的接口在浏览器中打开可以正常访问。
接口做了302重定向,从http重定向到https的地址去了。
Volley对重定向并没有额外处理,我们可以看https://github.com/mcxiaoke/android-volley的代码对重定向的处理,处理详情见BasicNetwork类。
在该类里,当程序发现响应返回的状态码是301或302时,则改动原请求的请求URL为重定向URL,然后抛出异常。
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
String newUrl = responseHeaders.get("Location");
request.setRedirectUrl(newUrl);//原请求指定重定向的URL
}
由于Volley有重试机制,对于响应失败的请求,会根据重试策略再次进行请求,此时,在while(true)里重新执行上次返回302的请求,则完成了对重定向的处理。
异常捕获的时候,对重定向状态单独处理,代码如下:
else if(statusCode==HttpStatus.SC_MOVED_PERMANENTLY||
statusCode==HttpStatus.SC_MOVED_TEMPORARILY) {
attemptRetryOnException("redirect",//attemptRetryOnException方法见前述
request,newRedirectError(networkResponse));//返回302则抛出重定向异常
}
但是这种对重定向的解决方案并不能满足一些场景,比如:
1、原请求是POST请求,但是重定向一般是GET请求,这样只改变原请求的访问地址,并不一定能请求成功。
2、重定向请求需要带的头信息与原请求不一致的,比如重定向是跨域的,可能需要对cookie处理。
除此之外,这种解决方案需要指定重试策略,但Volley默认是不重试的,而且我认为,大多数场景下,系统并不需要自动重试,而是由用户自己重新发起请求。这样一来,为了重定向需要单独指定重试策略,对代码的统一处理略有不便。
既然这种方案不能满足需求,那就需要改动源码了。
重定向的处理应该在访问请求的最底层处理比较合适,可以在HurlStack里处理。
自己处理重定向需要对connection加句代码:
connection.setInstanceFollowRedirects(false)
处理重定向的时候需要满足递归性,也就是说,A地址重定向到B地址,B地址又重定向到C地址,无限重定向,要能持续处理,并且原路返回结果。
HurlStack处理请求的方法是
public HttpResponse performRequest(Request request,Map additionalHeaders)
这里的入参是request对象,改动原request对象重新请求是比较麻烦的,而且由于是子线程里运行的,容易出现很多难解的问题。
理想的方式是构造新的请求,但是不能是构造新的Request对象,因为我们还要通过入参的request对象原路返回结果。
这时需要将performRequest方法里执行请求的代码提炼出一个方法来
private HttpResponse executeRequest(int method,String url,Map headers, byte[] postBody,
int timeoutMs,String contentType)
并且对重定向的处理如下:
if(responseStatus.getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY||
responseStatus.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) {
String redirectUrl = connection.getHeaderField("Location");
if(redirectUrl !=null&& redirectUrl.length() >0) {
return executeRequest(Method.GET,redirectUrl,headers, null,timeoutMs,contentType);
}
}
相应的,本类的一些其他的被调用方法由于入参类型问题也需要相应的变动,不过整体来说,改动还是很简单的。
另外可以增加两个方法onPrepareRequest、onReponseFinished;onPrepareRequest方法在请求调用之前执行,onReponseFinished可以在请求调用之后,重定向之前执行。空实现即可,需要的时候,在子类里处理即可,可以用于打印日志或者处理头信息等。
虽然改动量相对来说,略多,但是对一些场景来说,还是需要的。当然,如果重试机制的处理方式即可满足需求,那就无需动源码了。
为您推荐
公司项目H5调用接口遇到Response for preflight has invalid HTTP status code 405这样的错误,是使用PUT方式提交请求接口。Content-Type设置为application/json,JS代码如下:$.ajax({type:"PUT",url:"http://172.1..
.NET Core上传文件本地调试正常,部署到IIS服务器之后会报错,错误是Access 'c:\\windows\\temp\\xxx.tmp' is denied.看上去是IIS用户没有权限访问系统临时文件夹的权限。经过测试,不需要特地去为temp文件..
@helper 是 ASP.NET Razor 视图引擎的一种语法,它允许你在 Razor 视图中定义和使用自定义 HTML 帮助程序。这些帮助程序可以被多次调用,以生成复杂的 HTML。在ASP.NET MVC中可以使用@helper定义一个返回IHtmlString..
在 ASP.NET Core 中,获取请求的引用(Referrer)URL可以使用 HttpContext.Request.Headers 来访问,引用(Referrer)URL存储在请求的头部信息中,头部名称为 "Referer"。以下是如何在 ASP.NET Core 中获取请求的引..
在 VS Code 中创建 C# MVC 脚手架有两种方法:方法一:使用命令行打开一个终端窗口,并导航到您要创建项目的目录。输入以下命令:dotnet new mvc --name MyApp这将创建一个名为 MyApp 的新 C# MVC 项目。方法二:使..
.NET 8 中引入了 System.Net.IPNetwork 类,它是一个用于处理 IP 地址和网络的实用程序类。以下是 IPNetwork 类的基本用法:创建 IPNetwork 对象using System;using System.Net;class Program{static void Main(){//..
编译.net core项目出现如下错误:必须添加对程序集"netstandard, Version=2.0.0.0"。解决方法是更新.net core2,升级vs2017到15.4版本,升级framework到4.7版本。..
在服务器上安装了filezilla服务器软件后,使用FlashFXP上传下载文件失败。网上找了一些关于这个文件的解决方案,分享一下希望可以帮到大家。使用FlashFXP默认设置的话,无法打开FTP目录。首先、需要设置使用“STAL -..
git pull的时候提示Auto packing the repository in background for optimum performance执行命令:git fsck lost-foundgit gc prune=now执行需要一段时间,如图所示:执行完成后再pull就成功了。..
npm install echartsnpm install ngx-echarts安装使用echarts运行时报如下错误ERROR NullInjectorError: R3InjectorError(IndexModule)[InjectionToken NGX_ECHARTS_CONFIG -> InjectionToken NGX_ECHARTS_CONFIG -..
JSON是各种编程语言中都很常用的数据格式,如Java,JavaScript,C#等语言中都常用JSON传输数据或保存一些配置信息,要序列化或反序列化字符串,在代码中需要有对应与JSON内容的类才方便实现。vscode是非常强大的插件..
做了一个react的纯前端的应用,想要使用Android Studio创建一个安卓app通过WebView内嵌。创建app和启动页之前有讲过Android Studio Dolphin创建app启动页Splash自动跳转https://www.leavescn.com/Articles/Content/1..
好久没有使用Android Studio了,想要创建一个app内嵌一个react的前端应用。下载最新版的Android Studio Dolphin下载地址:https://developer.android.google.cn/studio创建一个新的app,选择Empty的模版即可。然后创..
使用vscode打开一个有中文注释的代码,发现中文显示是乱码,一般是因为文件编码的问题。可以采取一下两种方法来避免vscode中显示中文乱码的问题:方法一:在vscode右下角的有编码显示,如UTF-8,单击一下,上面正中..
为React项目编写单元测试时报错Error: thrown: "Exceeded timeout of 5000 ms for a test. Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."检查上下代码后是发现..
在 JavaScript 中,可以使用第三方库来生成二维码,其中最常用的是 qrcode.js。以下是使用 qrcode.js 生成二维码的示例代码:首先,在 HTML 文件中引入 qrcode.js 库文件:<script src="https://cdn.staticfile.org/..
网页没有响应,错误代码: RESULT_CODE_HUNG 的原因可能有以下几种:网页服务器宕机或超负荷网页服务器与客户端的网络连接断开网页服务器正在进行维护或升级网页客户端的网络环境不佳网页客户端的浏览器版本过低如果..
问题描述在运行一个c/c++的程序时,报如下错误:ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete)。代码如下:void DemoFunc(char *pBuf){char* val2 = new char[256];for (i..
如果在 Visual Studio 2019 中使用 NuGet 搜索时遇到错误,可能是由于以下几种常见原因:网络连接问题:确保你的计算机正常连接到互联网,检查防火墙或代理设置是否阻止了 NuGet 的访问。NuGet 源配置错误:在 Visua..
问题描述在Windows10系统中,由于切换了用户,导致在使用vscode通过ssh连接远程的linux系统是报错Bad owner or permissions on C:\Users\用户名/.ssh/config,删掉这个config文件都不行。解决方法下载OpenSSH:下载..