我在我开发的应用中遇到了一个问题 - 各种用户报告他们遇到了连接问题(仅限我的应用)。 例如:
我的应用通过HttpUrlConnection(HTTPS)连接到基于REST的API。
我的一个错误是我真的无法知道用户手机上发生了哪些网络错误(错误消息表示通用的“无网络”)。 我已经实施了有限的重试以弥补这个问题,但我不知道其他可能出错的地方。
我的主要网络代码附在下面,我向所有有经验的网络程序员提问:
- >请不要建议“使用HTTPClient而不是HttpUrlConnection”
创建POST请求的代码:
public static HTTPURLResponseHolder doHTTPPost(URL url, List<NameValuePair> headers, String body, String charset, boolean followRedirect,
SSLContext context) throws IOException {
HttpURLConnection connection = getConfiguredConnection(url, headers, charset, context, true);
// WORKAROUND for recycling issue...
// http://stackoverflow.com/questions/19258518/
connection.setRequestProperty("Connection", "close");
connection.setRequestMethod("POST");
int contentLength = 0;
if (body != null) {
contentLength = body.getBytes().length;
}
try {
connection.setFixedLengthStreamingMode(contentLength);
BufferedOutputStream stream = null;
try {
OutputStream outputStream = null;
if (body != null) {
outputStream = connection.getOutputStream();
stream = new BufferedOutputStream(outputStream);
stream.write(body.getBytes());
stream.flush();
}
} finally {
close(stream);
}
InputStream inputStream = connection.getInputStream();
HTTPURLResponseHolder holder = new HTTPURLResponseHolder();
int responseCode = connection.getResponseCode();
holder.setResponseCode(responseCode);
// Normal case:
String o = StreamUtility.inputStreamToString(inputStream, charset);
close(inputStream);
holder.setOutput(o);
return holder;
} catch (IOException e) {
return handleIOException(url, headers, charset, false, context, connection);
} finally {
connection.disconnect();
}
}
static HttpURLConnection getConfiguredConnection(URL url, List<NameValuePair> httpHeaders, String charset, SSLContext context, boolean doOutput)
throws IOException {
if (url == null || url.getProtocol() == null || !url.getProtocol().toLowerCase(Locale.US).startsWith("http")) {
throw new IllegalArgumentException("Invalid HTTP URL: " + url);
}
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
connection.setDoInput(true); // Read
if (doOutput) {
connection.setDoOutput(doOutput);
}
// Workaround for older Android versions who do not do that automatically (2.3.5 for example)
connection.setRequestProperty(HTTP.TARGET_HOST, url.getHost());
connection.setRequestProperty("Accept-Encoding", charset);
// Langauge
String language = Locale.getDefault().getLanguage();
if (StringUtility.isNullOrEmpty(language)) {
language = Locale.US.getLanguage();
}
connection.setRequestProperty("Accept-Language", language);
// Add the headers, if they exist
if (httpHeaders != null) {
for (NameValuePair nvp : httpHeaders) {
if (nvp != null) {
connection.setRequestProperty(nvp.getName(), nvp.getValue());
}
}
}
return connection;
}