以下代碼可以正常工作,以便對我的寧靜Web服務進行HTTPS調用。在Eclipse中構建和執行一個簡單的Java應用程序。如果直接調用HttpGet可以正常工作,但如果從Android活動調用時發出400響應
package test;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
@SuppressWarnings("unused")
public class Test {
private String filePath;
private InputStream inputStream = null;
private DefaultHttpClient hc = null;
public Test(String filePath) {
this.filePath = filePath;
try {
this.inputStream = new FileInputStream(filePath);
if (this.inputStream != null) {
Certificate myCert = CertificateFactory.getInstance("X.509")
.generateCertificate(this.inputStream);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("myCert", myCert);
SSLSocketFactory sf = new EasySSLSocketFactory(keyStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
hc = new DefaultHttpClient(ccm, params);
// Prepare a request object
String url = "https://service.cashyr.com:8443/PolarBear-0.0.1-SNAPSHOT/get_deals_dist/33.7445273910949/-118.10924671590328/12/0/aaaa";
HttpGet httpget = new HttpGet(url);
// Execute the request
HttpResponse response;
InputStream instream = null;
String data = null;
// // setSeeMoreDealsButton(context, false);
response = hc.execute(httpget);
HttpEntity entity = response.getEntity();
instream = entity.getContent();
if (instream != null) {
data = Utils.convertStreamToString(instream);
System.out.println(data);
}
}
}
catch (IOException e) {
e.printStackTrace();
hc = new DefaultHttpClient();
}
catch (Exception e) {
e.printStackTrace();
hc = new DefaultHttpClient();
}
}
public static void main(String[] args) {
new Test("service.cashyr.com.crt");
}
}
現在,我創建了Eclipse的另一個Android應用程序(不活動僅僅是一個簡單的按鈕,並在代碼中的聽衆一個簡單的活動連接到該按鈕。反正我在點擊監聽器運行此活動,並在它會運行一個AsyncTask來逐字運行所提到的HTTPS調用,它會返回一個400響應。爲什麼會這樣呢?我完全搞不清楚,因爲我確信我遵循了所有的HTTPS過程,顯然不是完全確定,但它適用於直接的Java應用程序。爲什麼會這樣?請幫助!!!!
Android的活動如下:
個package com.example.testandroidapp;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
Button button1;
private class ConnectionTask extends AsyncTask<String, Integer, String> {
protected void onPostExecute(String result) {
Log.d("MY_LOG", "Finished loading end point");
}
protected String doInBackground(String... arg) {
String url = arg[0];
Log.d("MY_LOG", "Started loading end point");
DefaultHttpClient hc = null;
String data = null;
try {
InputStream inputStream = MainActivity.class
.getResourceAsStream("service.cashyr.com.crt");
if (inputStream != null) {
Log.d("MY_LOG", "Loaded certificate file successfully");
Certificate myCert = CertificateFactory.getInstance(
"X.509").generateCertificate(inputStream);
// Log.d("MY_LOG", "Certificate contents:" + myCert.toString());
Log.d("MY_LOG", "Certificate object loaded");
KeyStore keyStore = KeyStore.getInstance(KeyStore
.getDefaultType());
Log.d("MY_LOG", "Obtained keystore");
keyStore.load(null, null);
Log.d("MY_LOG", "keystore loaded");
keyStore.setCertificateEntry("myCert", myCert);
Log.d("MY_LOG", "set certificate entry");
SSLSocketFactory sf = new EasySSLSocketFactory(keyStore);
Log.d("MY_LOG", "created SSL socket factory");
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Log.d("MY_LOG", "set host name verifier");
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params,
HttpVersion.HTTP_1_1);
HttpProtocolParams
.setContentCharset(params, HTTP.UTF_8);
Log.d("MY_LOG", "set up HTTP params");
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 8443));
Log.d("MY_LOG", "set up sche registry");
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
Log.d("MY_LOG", "created client connection manager object");
hc = new DefaultHttpClient(ccm, params);
Log.d("MY_LOG", "create default http client object for sending http request");
// Prepare a request object
HttpGet httpget = new HttpGet(url);
// Execute the request
HttpResponse response;
InputStream instream = null;
// // setSeeMoreDealsButton(context, false);
response = hc.execute(httpget);
Log.d("MY_LOG", "Sent https (SSL) get request.");
HttpEntity entity = response.getEntity();
instream = entity.getContent();
if (instream != null) {
data = Utils.convertStreamToString(instream);
Log.d("MY_LOG", "HTTPS response: \n" + data);
}
}
} catch (IOException e) {
e.printStackTrace();
hc = new DefaultHttpClient();
} catch (Exception e) {
e.printStackTrace();
hc = new DefaultHttpClient();
}
return data;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String url = "https://service.cashyr.com:8443/PolarBear-0.0.1-SNAPSHOT/get_deals_dist/33.7445273910949/-118.10924671590328/12/0/aaaa";
new ConnectionTask().execute(url);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
感謝, 傑夫
附: logcat的是在這裏:
08-01 09:24:51.003: D/memalloc(17677): ion: Unmapping buffer base:0x5bbed000 size:1536000
08-01 09:24:51.003: D/memalloc(17677): ion: Unmapping buffer base:0x5c070000 size:1536000
08-01 09:24:51.003: D/memalloc(17677): ion: Unmapping buffer base:0x5c2eb000 size:1536000
08-01 09:24:55.848: I/System.out(18055): Debugger has connected
08-01 09:24:55.848: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:56.048: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:56.258: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:56.448: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:56.649: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:56.859: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:57.049: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:57.259: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:57.449: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:57.650: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:57.850: I/System.out(18055): waiting for debugger to settle...
08-01 09:24:58.060: I/System.out(18055): debugger has settled (1401)
08-01 09:24:58.340: I/Adreno200-EGLSUB(18055): <ConfigWindowMatch:2218>: Format RGBA_8888.
08-01 09:24:58.350: D/memalloc(18055): ion: Mapped buffer base:0x5bced000 size:1536000 offset:0 fd:58
08-01 09:24:58.350: E/(18055): Can't open file for reading
08-01 09:24:58.350: E/(18055): Can't open file for reading
08-01 09:24:58.450: D/memalloc(18055): ion: Mapped buffer base:0x5c170000 size:1536000 offset:0 fd:62
08-01 09:25:04.146: D/memalloc(18055): ion: Mapped buffer base:0x5c2eb000 size:1536000 offset:0 fd:65
08-01 09:25:04.276: D/MY_LOG(18055): Started loading end point
08-01 09:25:04.426: D/MY_LOG(18055): Loaded certificate file successfully
08-01 09:25:04.847: D/MY_LOG(18055): Certificate object loaded
08-01 09:25:04.847: D/MY_LOG(18055): Obtained keystore
08-01 09:25:04.847: D/MY_LOG(18055): keystore loaded
08-01 09:25:04.847: D/MY_LOG(18055): set certificate entry
08-01 09:25:04.857: D/MY_LOG(18055): created SSL socket factory
08-01 09:25:04.857: D/MY_LOG(18055): set host name verifier
08-01 09:25:04.857: D/MY_LOG(18055): set up HTTP params
08-01 09:25:04.867: D/MY_LOG(18055): set up sche registry
08-01 09:25:04.877: D/MY_LOG(18055): created client connection manager object
08-01 09:25:04.887: D/MY_LOG(18055): create default http client object for sending http request
08-01 09:25:07.469: D/MY_LOG(18055): Sent https (SSL) get request.
08-01 09:25:07.479: D/MY_LOG(18055): HTTPS response:
08-01 09:25:07.479: D/MY_LOG(18055): <?xml version='1.0'?>
08-01 09:25:07.479: D/MY_LOG(18055): <!DOCTYPE html PUBLIC '-//WAPFORUM//DTD XHTML Mobile 1.0//EN'
08-01 09:25:07.479: D/MY_LOG(18055): 'http://www.wapforum.org/DTD/xhtml-mobile10.dtd'>
08-01 09:25:07.479: D/MY_LOG(18055): <html xmlns='http://www.w3.org/1999/xhtml'>
08-01 09:25:07.479: D/MY_LOG(18055): <head>
08-01 09:25:07.479: D/MY_LOG(18055): <title>The request failed</title>
08-01 09:25:07.479: D/MY_LOG(18055): </head>
08-01 09:25:07.479: D/MY_LOG(18055): <body>
08-01 09:25:07.479: D/MY_LOG(18055): <p><big>The request is not understood.</big></p>
08-01 09:25:07.479: D/MY_LOG(18055): <p>
08-01 09:25:07.479: D/MY_LOG(18055): <i>Technical description:</i><br/>400 Bad Request - Check your spelling for the requested URL</p>
08-01 09:25:07.479: D/MY_LOG(18055): </body>
08-01 09:25:07.479: D/MY_LOG(18055): </html>
08-01 09:25:07.479: D/MY_LOG(18055): Finished loading end point
你能分享YOUT logcat的? – Peshal
剛剛加上我修改了上面的代碼來顯示我的日誌語句。直到我添加了一些日誌記錄行之後,日誌貓纔不起眼。 –
我不知道爲什麼我得到以下內容: \t 08-01 09:24:58.350:E /(18055):無法打開文件以供讀取 \t 08-01 09:24:58.350:E /( 18055):無法打開文件進行閱讀 我似乎在每個從裸骨頭寫入複雜的Android應用程序中都看到了這一點。我承認它一定是SDK中的一些錯誤。 –