收到错误 java.io.IOException:服务器返回 HTTP 响应代码:401
Posted
技术标签:
【中文标题】收到错误 java.io.IOException:服务器返回 HTTP 响应代码:401【英文标题】:getting error java.io.IOException: Server returned HTTP response code: 401 for 【发布时间】:2012-07-02 08:13:01 【问题描述】:我正在尝试对 https url 进行身份验证,但我遇到了异常。下面是代码。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
public class Authenticate
/**
* @param args
*/
public void authenticateUrl()
HostnameVerifier hv = new HostnameVerifier()
@Override
public boolean verify(String urlHostName, SSLSession session)
System.out.println("Warning: URL Host: " + urlHostName
+ " vs. " + session.getPeerHost());
return true;
;
// Now you are telling the JRE to trust any https server.
// If you know the URL that you are connecting to then this should
// not be a problem
try
trustAllHttpsCertificates();
catch (Exception e)
System.out.println("Trustall" + e.getStackTrace());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try
URL url = new URL(
"www.***.com");
// Popup Window to request username/password password
// MyAuthenticator ma = new MyAuthenticator();
String userPassword = "user" + ":" + "pass";
// Encode String
String encoding = URLEncoder.encode(userPassword, "UTF-8");
// or
// String encoding = Base64Converter.encode
// (userPassword.getBytes());
// Need to work with URLConnection to set request property
URLConnection uc = url.openConnection();
uc.setRequestProperty("Authorization", "UTF-8" + encoding);
InputStream content = (InputStream) uc.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(
content));
String line;
while ((line = in.readLine()) != null)
pw.println(line);
catch (MalformedURLException e)
e.printStackTrace();
pw.println("Invalid URL");
catch (IOException e)
e.printStackTrace();
pw.println("Error reading URL");
catch (Exception e)
e.printStackTrace();
sw.toString();
public static void main(String[] args)
// TODO Auto-generated method stub
Authenticate au = new Authenticate();
au.authenticateUrl();
// Just add these two functions in your program
public static class TempTrustedManager implements
javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager
public java.security.cert.X509Certificate[] getAcceptedIssuers()
return null;
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs)
return true;
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs)
return true;
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException
return;
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException
return;
private static void trustAllHttpsCertificates() throws Exception
// Create a trust manager that does not validate certificate chains:
javax.net.ssl.TrustManager[] trustAllCerts =
new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new TempTrustedManager();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc =
javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
例外:
java.io.IOException: Server returned HTTP response code: 401 for URL:
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at Authenticate.authenticateUrl(Authenticate.java:62)
at Authenticate.main(Authenticate.java:84)
请任何人建议如何解决此问题。
【问题讨论】:
我希望这不是您的真实用户名和密码...如果是,立即更改 【参考方案1】:另一种简单的方法是使用Authenticator。
来自文档
Authenticator 类表示一个知道如何获得网络连接身份验证的对象。通常,它会通过提示用户输入信息来做到这一点。
URL url = null;
try
url = new URL("YOUR_URL");
Authenticator.setDefault(new Authenticator()
protected PasswordAuthentication getPasswordAuthentication()
return new PasswordAuthentication("YOUR_USERNAME","YOUR_PASSWORD".toCharArray());
);
catch (MalformedURLException ex)
e = new WebServiceException(ex);
【讨论】:
【参考方案2】:在这里您可以处理错误代码 401。 使用 HTTPURLCONNECTION 这是我的代码,请检查你可以帮助这个
URL Url = new URL(<your url string>);
HttpURLConnection connection = (HttpURLConnection) Url.openConnection();
connection.setRequestProperty(<your request header);
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == 200)
InputStream is = connection.getInputStream();
if (is != null)
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
response = rd.readLine();
else InputStream is = connection.getErrorStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
response = rd.readLine();
if (response != null)
AppLog.e("Response-->", response);
【讨论】:
【参考方案3】:401 错误代码表示“未经授权”。我相信您的代码没有正确编码 Authentication 标头。假设服务器需要基本访问身份验证,代码应如下所示:
String credentials = "ptt" + ":" + "ptt123";
String encoding = Base64Converter.encode(credentials.getBytes("UTF-8"));
URLConnection uc = url.openConnection();
uc.setRequestProperty("Authorization", String.format("Basic %s", encoding));
在RFC 2617 中提供了对 HTTP 基本和摘要身份验证方案的全面描述
【讨论】:
+1 它对我有用...但我宁愿使用String encoding = org.apache.catalina.util.Base64.encode(credentials.getBytes("UTF-8"));
谢谢一百万
+1 我一直在努力使用正确的编码器。这对我有帮助。我使用的是org.apache.commons.codec.binary.Base64
,这是错误的基本授权。 正确的一个是你org.apache.tools.ant.util.Base64Converter
以上是关于收到错误 java.io.IOException:服务器返回 HTTP 响应代码:401的主要内容,如果未能解决你的问题,请参考以下文章
Proguard 错误:“处理任务 java.io.IOException 时出现异常:请先更正上述警告”
为啥我收到 java.io.IOException: Mark has been invalidated?
java.io.IOException:android 连接上的流意外结束
Gradle 构建失败 java.io.IOException:输出 jar 为空