我正在使用AsyncHttpClient
链接进行HTTP调用,但现在我们的服务器已迁移到HTTPS,并且我收到异常javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
。有没有人尝试过使用此库进行https调用?
AsyncHttpClient 的初始化 :-
AsyncHttpClient client = new AsyncHttpClient();
PersistentCookieStore myCookieStore = new PersistentCookieStore(
getActivity());
// List<Cookie> cookies = myCookieStore.getCookies();
myCookieStore.clear();
// cookies = myCookieStore.getCookies();
client.setCookieStore(myCookieStore);
client.get(loginUrl, new JsonHttpResponseHandler() {
@Override
public void onStart() {
super.onStart();
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onFinish() {
super.onFinish();
progressBar.setVisibility(View.GONE);
}
@Override
public void onSuccess(int statusCode, JSONObject userInfo) {
super.onSuccess(statusCode, userInfo);
String errorMsg = null;
try {
errorMsg = userInfo.getString("error");
} catch (JSONException e) {
e.printStackTrace();
}
if (errorMsg != null) {
errorMsg = getActivity().getResources().getString(
R.string.loginFailure)
+ "nError: " + errorMsg;
tvLoginFailure.setText(errorMsg);
tvLoginFailure.setVisibility(View.VISIBLE);
} else {
Subscriber.setEmail(email);
Subscriber.setPassword(password);
LoginUtility.saveUserInfo(getActivity(), userInfo);
if (Subscriber.getStatus().contentEquals("ACTIVE")) {
Intent intent;
if (MyApplication.ottMode) {
intent = new Intent(getActivity(),
OTTMainScreen.class);
} else {
intent = new Intent(getActivity(),
MainActivity.class);
intent.putExtra("SIGNEDIN", true);
}
if (MyApplication.ottMode) {
Utility.playSound(getActivity());
}
startActivity(intent);
getActivity().finish();
} else if (Subscriber.getStatus().contentEquals(
"SUSPENDED")) {
try {
String suspendedReason = userInfo
.getString("suspendreason");
if (suspendedReason != null
&& suspendedReason
.contentEquals("NO_SUBSCRIPTION")) {
new AlertDialog.Builder(getActivity())
.setIcon(
android.R.drawable.ic_dialog_alert)
.setTitle("Account Suspended")
.setMessage(
"Your account doesn't have any active subscription. You need to subscribe to a Package before you can proceed.")
.setPositiveButton(
"Subscribe",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
recreatePackage();
}
})
.setNegativeButton("Cancel", null)
.show();
} else {
// TODO
}
} catch (JSONException e) {
e.printStackTrace();
}
} else if (Subscriber.getStatus().contentEquals("INIT")) {
// TODO
}
}
}
@Override
public void onFailure(int statusCode,
org.apache.http.Header[] headers, String responseBody,
Throwable e) {
super.onFailure(statusCode, headers, responseBody, e);
String msg = getActivity().getResources().getString(
R.string.loginFailure)
+ "nError: " + responseBody;
tvLoginFailure.setText(msg);
tvLoginFailure.setVisibility(View.VISIBLE);
}
});
您需要将公共服务器证书导入到缺省密钥库中,或者如果您对客户机的认证不感兴趣,则可以使用 初始化AsyncHttpClient
AsyncHttpClient asycnHttpClient = new AsyncHttpClient(true, 80, 443);
但是这个技巧并不安全,因为使用自定义SSLSocketFactory实现谁省略了SSL证书验证,看看AsyncHttpClient源代码。
有关SSLSocketFactory的更多信息,请访问 https://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html
你也可以通过添加这 1 行来解决这个问题。
asyncHttpClient.setSSLSocketFactory(MySSLSocketFactory.getFixedSocketFactory());
我有一个简单的 http 客户端,它调用 https 服务:
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
/**
*/
public class HttpSimpleClient {
private static final String TAG = HttpSimpleClient.class.getSimpleName();
private static HttpSimpleClient instance;
private HttpSimpleClient(){}
public static HttpSimpleClient instance(){
if (instance==null) {
instance = new HttpSimpleClient();
}
return instance;
}
public <T> T post(URL url,
List<NameValuePair> header,
List<NameValuePair> parameter,
ResponseHandler<T> responseHandler) throws IOException {
return post(url, header, parameter, responseHandler, null, null);
}
public <T> T post(URL url,
List<NameValuePair> header,
List<NameValuePair> parameter,
ResponseHandler<T> responseHandler,
AuthScope proxy,
UsernamePasswordCredentials proxyUser) throws IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(url.toString());
if (header!=null) {
for (NameValuePair head : header){
request.setHeader(head.getName(), head.getValue());
}
Log.d(TAG, "Aggiunti header: "+ header.size());
} else {
// Header di default
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
request.setHeader("User-Agent", System.getProperty("http.agent"));
Log.d(TAG, "Aggiunti header di defautl");
}
if (parameter!=null) {
request.setEntity(new UrlEncodedFormEntity(parameter, HTTP.UTF_8));
Log.d(TAG, "Aggiunti parametri: "+ parameter.size());
}
if (proxy!=null) {
if (proxyUser!=null) {
((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, proxyUser);
} else {
// TODO gestire proxy senza credenziali
((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, null);
}
Log.d(TAG, "Impostato Proxy per la connessione");
}
return httpClient.execute(request, responseHandler);
}
public static String httpResponseToString(HttpResponse httpResponse, int bufferSize) throws IOException {
InputStream content = httpResponse.getEntity().getContent();
int numRead;
byte[] buffer = new byte[bufferSize];
ByteArrayOutputStream outString = new ByteArrayOutputStream();
try{
while ((numRead = content.read(buffer)) != -1) {
outString.write(buffer, 0, numRead);
}
} finally {
content.close();
}
return new String(outString.toByteArray());
}
}
我在AsyncTask中使用它:
response = HttpSimpleClient.instance().post(
getServiceURL(), // HTTPS url
mHeader, // List<NameValuePair>
mParameter, // List<NameValuePair>
getResponseHandler() // org.apache.http.client.ResponseHandler
);
在安卓 api 上测试>=10
这是我的代码:
private Map<String, String> mParams;
public void sendata(View v) throws JSONException {
username = (EditText) findViewById(R.id.txtusername);
password = (EditText) findViewById(R.id.txtpassword);
final ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
JSONObject j = new JSONObject();
j.put("password", password.getText());
j.put("username", username.getText());
j.put("Deviceid", 123456789);
j.put("RoleId", 1);
String url = Url;
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("json", j.toString());
client.post(url, params, new JsonHttpResponseHandler() {
@SuppressLint("NewApi")
public void onSuccess(JSONObject response) {
pDialog.hide();
JSONObject jsnObjct;
try {
JSONObject json = (JSONObject) new JSONTokener(response
.toString()).nextValue();
JSONObject json2 = json.getJSONObject("Data");
JSONArray test = (JSONArray) json2
.getJSONArray("PatientAllergies");
for (int i = 0; i < test.length(); i++) {
json = test.getJSONObject(i);
System.out.print(json.getString("PatientId"));
System.out.print(json.getString("Id"));
System.out.print(json.getString("AllergyName"));
System.out.print(json.getString("Reaction"));
System.out.print(json.getString("OnSetDate"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void onFailure(int statusCode, Header[] headers, String res,
Throwable t) {
pDialog.hide();
}
});
}
JSONObject jsonObject;
private void parsejson(JSONObject response) {
try {
jsonObject = response;
System.out.print(response.toString());
JSONObject jsnObjct = jsonObject.getJSONObject("Data");
System.out.print(jsonObject.toString());
jsnObjct = jsnObjct.getJSONObject("PhysicianDetail");
System.out.print(jsnObjct.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}