gpt4 book ai didi

android - HttpURLConnection.getResponseCode() 卡住执行/不超时

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:50:14 24 4
gpt4 key购买 nike

我正在编写一个连接到受密码保护的 cPanel 服务器 (Apache 2.2.22) 页面的 Android 应用程序。当身份验证凭据正确时,连接没有问题。但是,当凭据不正确时,我的 Android 应用程序似乎在 HttpURLConnection.getResponseCode() 方法中卡住。服务器上的日志显示从我的 Android 设备发送了数百个请求,所有请求都按预期返回了 401,但出于某种原因,这并没有反射(reflect)在我的应用程序中。

这是我的代码,在 AsyncTask 中执行:

    @Override
protected Integer doInBackground(String... bookInfoString) {
// Stop if cancelled
if(isCancelled()){
return null;
}
Log.i(getClass().getName(), "SendToDatabase.doInBackground()");

String apiUrlString = getResources().getString(R.string.url_vages_library);
try{
NetworkConnection connection = new NetworkConnection(apiUrlString);
connection.appendPostData(bookInfoString[0]);
int responseCode = connection.getResponseCode();
Log.d(getClass().getName(), "responseCode: " + responseCode);
return responseCode;
} catch(IOException e) {
return null;
}

}

此代码使用了我自己的类 NetworkConnection,它只是一个围绕 HttpURLConnection 的基本包装类,以避免重复代码。在这里:

public class NetworkConnection {

private String url;
private HttpURLConnection connection;

public NetworkConnection(String urlString) throws IOException{
Log.i(getClass().getName(), "Building NetworkConnection for the URL \"" + urlString + "\"");

url = urlString;
// Build Connection.
try{
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(1000 /* 1 seconds */);
connection.setConnectTimeout(1000 /* 1 seconds */);
} catch (MalformedURLException e) {
// Impossible: The only two URLs used in the app are taken from string resources.
e.printStackTrace();
} catch (ProtocolException e) {
// Impossible: "GET" is a perfectly valid request method.
e.printStackTrace();
}
}

public void appendPostData(String postData) {

try{
Log.d(getClass().getName(), "appendPostData() called.\n" + postData);

Log.d(getClass().getName(), "connection.getConnectTimeout(): " + connection.getConnectTimeout());
Log.d(getClass().getName(), "connection.getReadTimeout(): " + connection.getReadTimeout());

// Modify connection settings.
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");

// Get OutputStream and attach POST data.
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write(postData);
if(writer != null){
writer.flush();
writer.close();
}

} catch (SocketTimeoutException e) {
Log.w(getClass().getName(), "Connection timed out.");
} catch (ProtocolException e) {
// Impossible: "POST" is a perfectly valid request method.
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// Impossible: "UTF-8" is a perfectly valid encoding.
e.printStackTrace();
} catch (IOException e) {
// Pretty sure this is impossible but not 100%.
e.printStackTrace();
}
}

public int getResponseCode() throws IOException{
Log.i(getClass().getName(), "getResponseCode()");
int responseCode = connection.getResponseCode();
Log.i(getClass().getName(), "responseCode: " + responseCode);
return responseCode;
}

public void disconnect(){
Log.i(getClass().getName(), "disconnect()");
connection.disconnect();
}
}

最后,这是 logcat 日志的一部分:

05-03 11:01:16.315: D/vages.library.NetworkConnection(3408): connection.getConnectTimeout(): 1000
05-03 11:01:16.315: D/vages.library.NetworkConnection(3408): connection.getReadTimeout(): 1000
05-03 11:01:16.585: I/vages.library.NetworkConnection(3408): getResponseCode()
05-03 11:04:06.395: I/vages.library.MainActivity$SendToDatabase(3408): SendToDatabase.onPostExecute(null)

您可以看到该方法似乎只是在随机时间后返回 null。我等待的最长时间恰好是 15 分钟。在我省略的最后两个信息日志之间,还有一些来自 dalikvm 的内存日志 (GC_CONCURRENT)。

我还应该说,目前我没有使用 https,尽管我认为这不会导致任何问题。我将非常感谢对此的任何反馈,无论是完整的答案还是只是告诉我不是问题的评论,因为我仍然不确定这个问题是服务器端还是客户端-边。

非常感谢,威廉

编辑:我之前忘了提到,我将我的身份验证凭据附加到我自己的自定义 java.net.Authenticator:

public class CustomAuthenticator extends Authenticator {

Context mContext;

public CustomAuthenticator(Context context){
super();
mContext = context;
}

@Override
protected PasswordAuthentication getPasswordAuthentication() {

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
String username = sharedPreferences.getString(SettingsActivity.KEY_USERNAME_PREFERENCE, null);
String password = sharedPreferences.getString(SettingsActivity.KEY_PASSWORD_PREFERENCE, null);

return new PasswordAuthentication(username, password.toCharArray());
}
}

我在 Activity 的onCreate() 方法中设置:

Authenticator.setDefault(new CustomAuthenticator(mContext));

另外,我已经使用 curl 请求受密码保护的资源,并且收到了预期的 401。我现在假设问题出在客户端。

最佳答案

这似乎是一个 issue在 POST 连接中使用 Authenticator。它很旧,所以我不知道它是否还存在。

我会尝试两件事:

  • AuthenticatorgetPasswordAuthentication 中添加一行日志,以查看它是否被有效调用。如果没有打印任何内容,您应该在调用之前检查是否添加了默认的 Authenticator。您说您在 onCreate() 中执行此操作,所以它应该没问题,但最好确定一下。
  • 避免使用身份验证器(至少出于测试目的)并直接在 HTTP 请求中发送身份验证信息。我通常这样做:

    String auth = user + ":" + pass;
    conn = (HttpURLConnection) url.openConnection();
    conn.setRequestProperty("Authorization",
    "Basic " + Base64.encode(auth.getBytes()));
    // Set other parameters and read the result...

关于android - HttpURLConnection.getResponseCode() 卡住执行/不超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16357884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com