java - 如果直接调用,HttpGet 工作正常,但如果从 Android Activity 调用,则会发出 400 响应

标签 java android https

以下代码可以很好地对我的 Restful Web 服务进行 HTTPS 调用。在 Eclipse 中构建并执行一个简单的 Java 应用程序。

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 应用程序(不是 Activity ,只是一个带有简单按钮的简单 Activity ,代码中的监听器连接到该按钮。无论如何,我运行此 Activity ,并在单击监听器中运行一个AsyncTask 逐字运行上述 HTTPS 调用,它返回 400 响应。为什么会这样?我完全困惑,因为我确信我遵循了执行 HTTPS 的所有程序。显然不完全确定,因为它不起作用。但是它可以与直接的 Java 应用程序一起使用。这是为什么?请帮助!!!!

Android Activity 如下:

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

最佳答案

好的,大家看看这个,保持简单 - 这不是脚本不好,不,先生.. 您的 Web.Config 可能存在 HTTP 冲突,400 错误要求加载没有响应的网页。因此,您必须检查一些小细节,因为您知道脚本很好,所以现在您必须检查您的设置以及计算机和浏览器的响应方式...

要解决试试这个 首先清除您的 DNS 缓存并删除 cookie 1. 重置您的网络浏览器,然后转到脚本,将 website.com 替换为实际的网址。 2. 对于服务,将 webHttpBinding 替换为 basicHttpBinding 3.确保标题行不长

记住保持简单 如需进一步帮助,请发送电子邮件给我 Frankieperez@yahoo.com

关于java - 如果直接调用,HttpGet 工作正常,但如果从 Android Activity 调用,则会发出 400 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17984879/

相关文章:

java - 如何按换行符拆分字符串?

php - 获取在 PHP 上不使用 curl 的网页(文本)的内容

java - 是否可以提高 AWT 图形绘制操作的精度?

java - 无法在 linux 中使用 javamail api 发送电子邮件

java - 将 jsonarray 转换为字符串

android - 开发 Android 游戏的正确方法

java - 代码对象 o = true ?新整数(0): new Long(1) returns Long with value 0. 为什么?

android - 使用 rngd 后,[hwrng] 继续最大化熵

Java 客户端证书和 keystore

java - 无法找到有效的认证路径