最近在维护项目过程中遇到网络请求的问题,使用口令登录网络请求正常,而使用指纹登录时会在httpclient的execute方法报错网络阻塞主线程。
下面就来说一下我的解决方案:
/**
*
* @param url
* 发送请求的URL
* 请求参数
* @return 服务器响应字符串
* @throws Exception
*/
public static String postRequestByUtf8(String url, Map<String, String> map)
throws Exception {
httpClient = getHttpClient();
// 创建HttpPost对象。
final HttpPost post = new HttpPost(url);
// 如果传递参数个数比较多的话可以对传递的参数进行封装
List<NameValuePair> params = new ArrayList<NameValuePair>();
for (String key : map.keySet()) {
// 封装请求参数
params.add(new BasicNameValuePair(key, map.get(key)));
}
// 设置请求参数
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
if (null != JSESSIONID) {
post.setHeader("Cookie", "JSESSIONID=" + JSESSIONID);
}
// 发送POST请求
/*在执行execute方法的时候,另外开启一个线程去执行,然后捕获异常,判断线程是否阻塞,然后
让线程沉睡2秒钟,调用thread.interrupt()打断状态,从而解决访问网络线程阻塞问题*/
if(httpClient != null) {
Thread thread = new Thread() {
@Override
public void run() {
try {
httpResponse = httpClient.execute(post);
} catch (IllegalArgumentException ec) {
httpResponse = null;
interrupted();
} catch (ClientProtocolException e) {
httpResponse = null;
interrupted();
e.printStackTrace();
} catch (IOException e) {
httpResponse = null;
interrupted();
e.printStackTrace();
}
}
};
thread.start();
try {
Thread.sleep(1000 * 2);
if (httpResponse == null) {
thread.interrupt();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 获取服务器响应字符串
String result = EntityUtils.toString(httpResponse.getEntity());
// 如果服务器成功地返回响应
if (httpResponse.getStatusLine().getStatusCode() == 200) {
List<Cookie> cookies = ((AbstractHttpClient) httpClient)
.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
if ("JSESSIONID".equals(cookies.get(i).getName())) {
JSESSIONID = cookies.get(i).getValue();
break;
}
}
return result;
}
throw new Exception(httpResponse.getStatusLine().getStatusCode()
+ "");
}
在执行execute方法的时候,另外开启一个线程去执行,然后捕获异常,判断线程是否阻塞,然后让线程沉睡2秒钟,调用thread.interrupt()打断状态解决问题。(ps:沉睡2s是必须的,不然后面的httpResponse.getEntity()会空指针异常)