在Android中保护HTTP发布
我有一个非常基本的帮助类,我正在使用所有的Http获取/发布的东西。 我使用的是来自org.apache.http库的HttpGet,HttpPost和HttpClient。 我所有的东西都可以通过HTTP正常工作,但是一旦我尝试使用通过HTTPS工作的服务,执行请求时就会收到ClientProtocolExceptionexception。 唯一的例外消息是“服务器无法响应有效的HTTP响应”。
为了testing,我使用一个简单的HTML表单和使用RequestBuilder的Fiddler2从浏览器发送完全相同的有效内容。 我发送了无效和空的有效负载,甚至发送了所有以上的头文件,看看是否有什么东西是对象的方式build设请求。
我在testing中使用的所有东西都给了我一个有效的200状态HTTP响应。 这个服务只是给了我一个描述错误的结构,如果我给它一些东西而不是它所期望的。
有什么特别的我需要添加到HttpPost或HttpClient对象(S)告诉它使用HTTPS? 我是否必须明确告诉它使用不同的端口?
编辑:
我确实为https通信注册了错误的套接字工厂。 这里是更新的方法,我使用正确的套接字工厂创build我的HttpClient对象,以防万一以后有人在search这种types的问题:
private HttpClient createHttpClient() { HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); return new DefaultHttpClient(conMgr, params); }
我不确定为什么你不能处理HTTPS。 我为自己的应用程序编写了一个助手类,并且能够通过HTTPS GET / POST没有问题。 我会在这里发布代码,也许你可以看到我的代码和你的代码是否有区别。
import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import android.util.Log; public class HttpRequest{ DefaultHttpClient httpClient; HttpContext localContext; private String ret; HttpResponse response = null; HttpPost httpPost = null; HttpGet httpGet = null; public HttpRequest(){ HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); httpClient = new DefaultHttpClient(myParams); localContext = new BasicHttpContext(); } public void clearCookies() { httpClient.getCookieStore().clear(); } public void abort() { try { if (httpClient != null) { System.out.println("Abort."); httpPost.abort(); } } catch (Exception e) { System.out.println("Your App Name Here" + e); } } public String sendPost(String url, String data) { return sendPost(url, data, null); } public String sendJSONPost(String url, JSONObject data) { return sendPost(url, data.toString(), "application/json"); } public String sendPost(String url, String data, String contentType) { ret = null; httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); httpPost = new HttpPost(url); response = null; StringEntity tmp = null; Log.d("Your App Name Here", "Setting httpPost headers"); httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE"); httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); if (contentType != null) { httpPost.setHeader("Content-Type", contentType); } else { httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); } try { tmp = new StringEntity(data,"UTF-8"); } catch (UnsupportedEncodingException e) { Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e); } httpPost.setEntity(tmp); Log.d("Your App Name Here", url + "?" + data); try { response = httpClient.execute(httpPost,localContext); if (response != null) { ret = EntityUtils.toString(response.getEntity()); } } catch (Exception e) { Log.e("Your App Name Here", "HttpUtils: " + e); } Log.d("Your App Name Here", "Returning value:" + ret); return ret; } public String sendGet(String url) { httpGet = new HttpGet(url); try { response = httpClient.execute(httpGet); } catch (Exception e) { Log.e("Your App Name Here", e.getMessage()); } //int status = response.getStatusLine().getStatusCode(); // we assume that the response body contains the error message try { ret = EntityUtils.toString(response.getEntity()); } catch (IOException e) { Log.e("Your App Name Here", e.getMessage()); } return ret; } public InputStream getHttpStream(String urlString) throws IOException { InputStream in = null; int response = -1; URL url = new URL(urlString); URLConnection conn = url.openConnection(); if (!(conn instanceof HttpURLConnection)) throw new IOException("Not an HTTP connection"); try{ HttpURLConnection httpConn = (HttpURLConnection) conn; httpConn.setAllowUserInteraction(false); httpConn.setInstanceFollowRedirects(true); httpConn.setRequestMethod("GET"); httpConn.connect(); response = httpConn.getResponseCode(); if (response == HttpURLConnection.HTTP_OK) { in = httpConn.getInputStream(); } } catch (Exception e) { throw new IOException("Error connecting"); } // end try-catch return in; } }
由于一些方法已被废弃,不应该是这样吗?
private DefaultHttpClient createHttpClient() { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(params, 10000); HttpConnectionParams.setSoTimeout(params, 10000); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); schReg.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); ClientConnectionManager conMgr = new PoolingClientConnectionManager(schReg); return new DefaultHttpClient(conMgr, params); }
我应该改变什么,比如HttpVersion?