这个问题是我在登录注册的时候出现的。Android客户端与DJANGO后台。我每次输入错误密码的时候就会出现上述错误,而输入正确的用户名密码是没有这个错误的。还有一个奇怪的现象:我写一个java测试代码的时候,输入错误的用户名和密码是不会抛出这个异常的,而我把该代码转移到Android程序里面,就会出现这个异常。真实让人费解。。。。
查了下源码发现HttpURLConnectionImpl.java,使用httpurlconnection请求http,有两种状态下会抛出这个异常:
/** * React to a failed authorization response by looking up new credentials. */ private Retry processAuthHeader(String responseHeader, String retryHeader) throws IOException { // keep asking for username/password until authorized String challenge = this.responseHeader.get(responseHeader); if (challenge == null) { throw new IOException("Received authentication challenge is null"); } String credentials = getAuthorizationCredentials(challenge); if (credentials == null) { return Retry.NONE; // could not find credentials, end request cycle } // add authorization credentials, bypassing the already-connected check requestHeader.set(retryHeader, credentials); return Retry.SAME_CONNECTION; }
/** * Returns the retry action to take for the current response headers. The * headers, proxy and target URL or this connection may be adjusted to * prepare for a follow up request. */ private Retry processResponseHeaders() throws IOException { switch (responseCode) { case HTTP_PROXY_AUTH: // proxy authorization failed ? if (!usingProxy()) { throw new IOException( "Received HTTP_PROXY_AUTH (407) code while not using proxy"); } return processAuthHeader("Proxy-Authenticate", "Proxy-Authorization"); case HTTP_UNAUTHORIZED: // HTTP authorization failed ? return processAuthHeader("WWW-Authenticate", "Authorization"); case HTTP_MULT_CHOICE: case HTTP_MOVED_PERM: case HTTP_MOVED_TEMP: case HTTP_SEE_OTHER: case HTTP_USE_PROXY: if (!getInstanceFollowRedirects()) { return Retry.NONE; } if (requestBodyOut != null) { // TODO: follow redirects for retryable output streams... return Retry.NONE; } if (++redirectionCount > MAX_REDIRECTS) { throw new ProtocolException("Too many redirects"); } String location = getHeaderField("Location"); if (location == null) { return Retry.NONE; } if (responseCode == HTTP_USE_PROXY) { int start = 0; if (location.startsWith(url.getProtocol() + ':')) { start = url.getProtocol().length() + 1; } if (location.startsWith("//", start)) { start += 2; } setProxy(location.substring(start)); return Retry.NEW_CONNECTION; } URL previousUrl = url; url = new URL(previousUrl, location); if (!previousUrl.getProtocol().equals(url.getProtocol())) { return Retry.NONE; // the scheme changed; don't retry. } if (previousUrl.getHost().equals(url.getHost()) && previousUrl.getEffectivePort() == url.getEffectivePort()) { return Retry.SAME_CONNECTION; } else { // TODO: strip cookies? requestHeader.removeAll("Host"); return Retry.NEW_CONNECTION; } default: return Retry.NONE; } }
说到这里,也间接说明一个前提条件,请求失败返回的是401错误,故响应头必须添加上”WWW-Authenticate“即可解决这个问题
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步