安卓 - HTTP GET 请求

11

我已经开发出一种明显有效的HTTP GET方法。

public class GetMethodEx {


public String getInternetData() throws Exception{

        new TrustAllManager();
        new TrustAllSSLSocketFactory();

        BufferedReader in = null;
        String data = null;


        try
        {
            HttpClient client = new DefaultHttpClient();
            URI website = new URI("https://server.com:8443/Timesheets/ping");
            HttpGet request = new HttpGet();
            request.setURI(website);
            HttpResponse response = client.execute(request);
            response.getStatusLine().getStatusCode();

            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String l = "";
            String nl = System.getProperty("line.separator");
            while ((l = in.readLine()) !=null){
                sb.append(l + nl);
            }
            in.close();
            data = sb.toString();
            return data;        
        } finally{
            if (in != null){
                try{
                    in.close();
                    return data;
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
}

这是我的模拟器从 www.google.com 获取响应时的截图:

GOOGLE.COM 正常工作的屏幕截图

以下代码是我使用的检索方法,用于在屏幕上显示它。

public class Home extends Activity {

TextView httpStuff;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.httpexample);
    httpStuff = (TextView) findViewById(R.id.tvhttp);
   new LongOperation().execute("");

}

private class LongOperation extends AsyncTask<String, Void, String> {
  @Override

  protected String doInBackground(String... params) {

      GetMethodEx test = new GetMethodEx();      
      String returned = null;

    try {
        returned = test.getInternetData();

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        return returned;
  }      

  @Override
  protected void onPostExecute(String result) {    
     httpStuff.setText(result);       
  }

然而,当我尝试在自己的服务器上运行时。

"https://server:port/xwtimesheets/ping"

我看到了以下屏幕。

我的服务器不工作

4个回答

8
这是您的GetMethodEx类的编辑版本。MySSLSocketFactory可让您连接任何服务器,而无需检查其证书。正如您所知,这不安全。我建议您将服务器的证书添加为设备的受信任证书。
顺便说一下,您的服务器证书有效期已过期。即使您将其添加为受信任的证书,也可能无法连接到服务器。
public class GetMethodEx {

public String getInternetData() throws Exception {


    BufferedReader in = null;
    String data = null;

    try {
        HttpClient client = new DefaultHttpClient();
        client.getConnectionManager().getSchemeRegistry().register(getMockedScheme());

        URI website = new URI("https://server.com:8443/XoW"); 
        HttpGet request = new HttpGet();
        request.setURI(website);
        HttpResponse response = client.execute(request);
        response.getStatusLine().getStatusCode();

        in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String l = "";
        String nl = System.getProperty("line.separator");
        while ((l = in.readLine()) != null) {
            sb.append(l + nl);
        }
        in.close();
        data = sb.toString();
        return data;
    } finally {
        if (in != null) {
            try {
                in.close();
                return data;
            } catch (Exception e) {
                Log.e("GetMethodEx", e.getMessage());
            }
        }
    }
}

public Scheme getMockedScheme() throws Exception {
    MySSLSocketFactory mySSLSocketFactory = new MySSLSocketFactory();
    return new Scheme("https", mySSLSocketFactory, 443);
}

class MySSLSocketFactory extends SSLSocketFactory {
    javax.net.ssl.SSLSocketFactory socketFactory = null;

    public MySSLSocketFactory(KeyStore truststore) throws Exception {
        super(truststore);
        socketFactory = getSSLSocketFactory();
    }

    public MySSLSocketFactory() throws Exception {
        this(null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
            UnknownHostException {
        return socketFactory.createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return socketFactory.createSocket();
    }

    javax.net.ssl.SSLSocketFactory getSSLSocketFactory() throws Exception {
        SSLContext sslContext = SSLContext.getInstance("TLS");

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sslContext.init(null, new TrustManager[] { tm }, null);
        return sslContext.getSocketFactory();
    }
}
}

@Akdeniz 你好!我尝试了你推荐的方法,但是出现了一些错误,我在Stack Overflow上发布了一个问题,请问你能告诉我哪里做错了吗?谢谢。http://stackoverflow.com/questions/23900054/android-php-sending-a-get-request-to-php-server - Ignacio Alorre

5

您这里有一个错误:

URI website = new URI("https://https://ts.xoomworks.com:8443/XoomworksTimesheets/ping");

您重复使用了"https://"。

编辑: 我从这里获取了代码。

您的代码应该如下所示:

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient client = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 8443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

// Set verifier      
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

// Example send http request
final String url = "https://ts.xoomworks.com:8443/XoomworksTimesheets/ping/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);

response.getStatusLine().getStatusCode();

in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null){
    sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;

我没有在我的端口上测试过,但它应该可以工作。请注意,您使用的是端口8433而不是433,因此我在socketfactory方案中进行了更改。


当你进行google.com请求时,你是不使用https进行请求的对吗?你尝试过在没有SSL连接的情况下向你的服务器发送请求吗? - Diego Sucaria
我也尝试过使用 Facebook,它使用了 https 协议。我的服务器没有 SSL 连接就无法工作。我有一个允许所有未签名证书的类,但我知道这是不安全的。但我不确定如何在我的代码中实现这个类。 - Lyanor Roze
这里有一个很好的例子,可以替换你的代码:HttpClient client = new MyHttpClient(); HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier()); String url = "https://ts.xoomworks.com:8443/XoomworksTimesheets/ping"; HttpGet request = new HttpGet(url); HttpResponse response = client.execute(request); - Diego Sucaria
刚刚测试了一下。我编辑了主要答案。对于你遇到的错误,请确保使用以下内容:"import org.apache.http.conn.ssl.SSLSocketFactory",而不是Java的sslsocketfactoyry。 - Diego Sucaria
谢谢,这个需要留在Try循环中吗? - Lyanor Roze
显示剩余4条评论

4

请注意,随着新版本API的发布,所有这些代码都被弃用了

以下是使用新API进行HTTP GET请求的示例

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Display the first 500 characters of the response string.
        mTextView.setText("Response is: "+ response.substring(0,500));
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mTextView.setText("That didn't work!");
    }
});
// Add the request to the RequestQueue.
queue.add(stringRequest);

从Android官方网站获取的信息: https://developer.android.com/training/volley/simple.html

这篇文章介绍了在Android应用程序中使用Volley库进行网络请求的简单方法。使用Volley可以使网络请求更加高效,因为它可以自动管理网络连接和线程,同时还提供了内置的缓存机制。


1

HttpClient已经被弃用。现在有一种新的方法: 首先,在build.gradle中添加这两个依赖项:

compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'

然后在ASyncTaskdoBackground方法中编写以下代码。

 URL url = new URL("http://localhost:8080/web/get?key=value");
 HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
 urlConnection.setRequestMethod("GET");
 int statusCode = urlConnection.getResponseCode();
 if (statusCode ==  200) {
      InputStream it = new BufferedInputStream(urlConnection.getInputStream());
      InputStreamReader read = new InputStreamReader(it);
      BufferedReader buff = new BufferedReader(read);
      StringBuilder dta = new StringBuilder();
      String chunks ;
      while((chunks = buff.readLine()) != null)
      {
         dta.append(chunks);
      }
 }
 else
 {
     //Handle else
 }

注意:不要忘记在代码中处理异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接