Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用httpclient 4.1.2连接到https会导致org.apache.http.client.ClientProtocolException_Java_Ssl_Httpclient - Fatal编程技术网

Java 使用httpclient 4.1.2连接到https会导致org.apache.http.client.ClientProtocolException

Java 使用httpclient 4.1.2连接到https会导致org.apache.http.client.ClientProtocolException,java,ssl,httpclient,Java,Ssl,Httpclient,我已成功地在android中使用发布到https服务器,接受所有证书 现在,我正在用JAVA尝试同样的方法向https服务器发送接受所有证书的邮件 我从上面的url修改了EasySSLSocketFactory类,因为SocketFactory、LayeredSocketFactory类在httpclient 4.1.2版本中不推荐使用EasyX509TrustManager以上url中的类保持不变。这是我修改过的EasySSLSocketFactory。我已经标记了我修改过的类 /* * L

我已成功地在android中使用发布到https服务器,接受所有证书

现在,我正在用JAVA尝试同样的方法向https服务器发送接受所有证书的邮件

我从上面的url修改了
EasySSLSocketFactory
类,因为
SocketFactory、LayeredSocketFactory
类在httpclient 4.1.2版本中不推荐使用<代码>EasyX509TrustManager以上url中的类保持不变。这是我修改过的
EasySSLSocketFactory
。我已经标记了我修改过的类

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.SchemeSocketFactory;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;


public class EasySSLSocketFactory implements SchemeSocketFactory
{
     private SSLContext sslcontext = null;

     private static SSLContext createEasySSLContext() throws IOException {
             try {
                     SSLContext context = SSLContext.getInstance("TLS");
                     context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
                     return context;
             } catch (Exception e) {
                     throw new IOException(e.getMessage());
             }
     }


    private SSLContext getSSLContext() throws IOException {
             if (this.sslcontext == null) {
                     this.sslcontext = createEasySSLContext();
             }
             return this.sslcontext;
     }

     /**
      * @see org.apache.http.conn.scheme.SchemeSocketFactory#isSecure(java.net.Socket)
      */
     public boolean isSecure(Socket socket) throws IllegalArgumentException {
             return true;
     }

     // -------------------------------------------------------------------
     // javadoc in org.apache.http.conn.scheme.SocketFactory says :
     // Both Object.equals() and Object.hashCode() must be overridden
     // for the correct operation of some connection managers
     // -------------------------------------------------------------------

     public boolean equals(Object obj) {
             return ((obj != null) && obj.getClass().equals(
                             EasySSLSocketFactory.class));
     }

     public int hashCode() {
             return EasySSLSocketFactory.class.hashCode();
     }

    //this method is modified
    @Override
    public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress,
            InetSocketAddress localAddress, HttpParams params) throws IOException,
            UnknownHostException, ConnectTimeoutException {

        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
        int soTimeout = HttpConnectionParams.getSoTimeout(params);
        SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket(params));
        if (localAddress != null) {
            // we need to bind explicitly
            sslsock.bind(localAddress);
    }

    sslsock.connect(remoteAddress, connTimeout);
    sslsock.setSoTimeout(soTimeout);
    return sslsock;
    }

    //this method is modified
    @Override
    public Socket createSocket(HttpParams arg0) throws IOException {
         return getSSLContext().getSocketFactory().createSocket();
    }

}
这是我的httpclient。由于使用了httpclient 4.1.2,这个类也被修改了

public class MyHttpClient extends DefaultHttpClient {

    /** The time it takes for our client to timeout */
    public static final int HTTP_TIMEOUT = 30 * 1000; // milliseconds
    public static final int SOCKET_TIMEOUT = 50 * 1000; // milliseconds


    public MyHttpClient() {
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
        // Register for port 443 our SSLSocketFactory to the ConnectionManager
        registry.register(new Scheme("https", 443, new EasySSLSocketFactory()));

        //setting the httpparams
        HttpParams params = new BasicHttpParams();
        //params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1);
        //params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1));
        params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
        //HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "utf8");

        return new SingleClientConnManager(registry);
    }

}
我正试图以以下方式连接

ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
        postParameters.add(new BasicNameValuePair("userid", userid));
        postParameters.add(new BasicNameValuePair("password", password));
        String newresponse = null;
        BufferedReader in = null;
        try{
             DefaultHttpClient client = new MyHttpClient();
             try {        
                    HttpPost req = new HttpPost(my https url);
                    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
                    req.setEntity(formEntity);
                    HttpResponse resp = client.execute(req);
                    in = new BufferedReader(new InputStreamReader(resp.getEntity().getContent()));
                    StringBuffer sb = new StringBuffer("");
                    String line = "";
                    String NL = System.getProperty("line.separator");
                    while ((line = in.readLine()) != null) {
                        sb.append(line + NL);
                    }
                    in.close();
                    newresponse = sb.toString();

                    }catch(Exception e){
                        LOGGER.error("Exception", e);
                    }finally {
                        if (in != null) {
                            try {
                                in.close();
                            } catch (IOException e) {
                                LOGGER.error("IOException: ",e);
                            }
                        }
                    }
        } catch(Exception e){
            LOGGER.debug("Connection Exception: ",e);
        }
我尝试访问的服务器正在使用我没有的来自verisign的证书。因此我尝试接受所有证书。将来我将更改此设置

有人能让它工作吗?
提前感谢。

您的
EasySslocketFactory
还必须实现
LayeredSchemeSocketFactory
接口,如果您希望它支持SSL隧道功能。

您还需要注册SSLSocketFactory的方案:

httpClient.getConnectionManager().getSchemeRegistry().register(
    new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory())
);

@oleg-谢谢你的回复。我会尝试一下,并让你保持联系。@oleg-我尝试过实现它,效果非常好。非常感谢
httpClient.getConnectionManager().getSchemeRegistry().register(
    new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory())
);