我在连续多次调用相同的 https URL 时遇到问题。第一次请求成功,但在不确定的时间后,抛出 401 HTTP 错误代码异常,表明用户凭据无效。
我和数据库/服务器的负责人讨论了这个问题,他告诉我我遇到的问题是正常的,因为在一段时间后,服务器使会话数据无效,导致后续调用相同的 URL用户凭据导致 401 HTTP 错误代码。
他指出,如果我让不同的 URLConnection 对象处理所有需要进行的调用,那么我不必担心会话数据过期。
他的解释似乎是有道理的,但正如下面的代码片段所示,我已经在使用全新的 URLConnection 对象来处理对具有相同用户凭据的相同 url 的每个请求。因此,如果我被告知的内容是正确的,那么我想问题在于 URLConnection 对象都使用相同的底层连接,因此共享相同的会话数据。
假设我走在正确的轨道上,我应该如何修改我的代码,以便每次使用相同的用户凭据向同一个 URL 发出新请求时,我不会遇到会话数据过期引起的问题?是否只是在底层 HttpsURLConnection 对象上调用 disconnect() 的问题?
public static void main(String[] args)
{
String url = "https://...";//some https url
int x = 0;
while(true)
{
try
{
System.out.print("call#: " + (++x));
//call download() with a valid username & password
String result = download(url, "some-valid-username", "some-valid-password");
System.out.println(result);
}
catch(Throwable e)
{
//after hundreds of successful calls,
//a 401 HTTP error code exception
e.printStackTrace();
break;
}
}
}
public static String download(String url, String user, String pass) throws IOException
{
//new URLConnection object
java.net.URLConnection connection = new java.net.URL(url).openConnection();
connection.setRequestProperty("Authorization",
"Basic " +
javax.xml.bind.DatatypeConverter.printBase64Binary(
(user + ":" + pass).getBytes("UTF-8")));
//get response
InputStream is = null;
byte[] response = null;
try
{
is = connection.getInputStream();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
byte[] bytes = new byte[16384];
int x = 0;
while((x = is.read(bytes, 0, bytes.length)) != -1){
stream.write(bytes, 0, x);
}
stream.flush();
response = stream.toByteArray();
}
finally
{
if (is != null)
{
is.close();
}
}
//((javax.net.ssl.HttpsURLConnection)connection).disconnect();// ?
return response != null ? new String(response, "UTF-8") : null;
}