将SSLSocketFactory存储为静态字段

时间:2015-08-20 10:52:06

标签: java android network-programming

我在我的android项目中使用以下代码片段连接到几个活动中的tomcat服务器,我想将它移动到另一个类 - 封装此代码片段。通过封装,我不必像以前那样通过每个连接加载和创建证书,密钥库和信任。

        URL url;
        HttpsURLConnection connection = null;
        try {
            // Load CAs from an InputStream
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = new BufferedInputStream(getAssets().open("my_certificate.crt"));
            Certificate ca = cf.generateCertificate(caInput);

            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            String urlParameters = SOME_PARAMETERS;
            url = new URL(SOME_URL);
            connection = (HttpsURLConnection) url.openConnection();
            connection.setSSLSocketFactory(context.getSocketFactory());

            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            connection.setRequestMethod("POST");
            connection.setFixedLengthStreamingMode(urlParameters.getBytes().length);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            PrintWriter out = new PrintWriter(connection.getOutputStream());
            out.print(urlParameters);
            out.close();

是否可以将前4个子段移动到新类的方法并将第一次调用的结果存储为静态字段?实施例

public class ConnectionPreparer {
    private static SSLSocketFactory sslSocketFactory;
    private Context context;
    public ConnectionPreparer (Context context){
        this.context = context;
    }
    private SSLSocketFactory getSSLSocketFactory(){
        if(sslSocketFactory==null){
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = new BufferedInputStream(context.getAssets().open("my_certificate.crt"));
            Certificate ca = cf.generateCertificate(caInput);

            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            sslSocketFactory = context.getSocketFactory();
        }
        return sslSocketFactory;
    }
    public HttpsURLConnection prepareConnection(){
        URL url = SOME_URL;            
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(getSSLSocketFactory());
        // and so on
    }
}

如果不是为什么不好?如果它还可以,我很高兴。

感谢您的关注!

1 个答案:

答案 0 :(得分:0)

是的,它有效。这是一个结果类。

import android.content.Context;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Scanner;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

/**
 * Created by Rinomancer on 20.08.2015.
 */
public class ConnectionBuilder {
    private static SSLSocketFactory sslSocketFactory;
    private Context context;
    private URL url;
    private String parameters = "";
    private String response;
    private HttpsURLConnection connection;

    public ConnectionBuilder() {

    }

    public ConnectionBuilder(Context context, URL url) {
        this.context = context;
        this.url = url;
    }

    private SSLSocketFactory getSSLSocketFactory() throws Exception {
        if (sslSocketFactory == null) {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = new BufferedInputStream(context.getAssets().open("my_certificate.crt"));
            Certificate ca = cf.generateCertificate(caInput);

            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            sslSocketFactory = context.getSocketFactory();
        }
        return sslSocketFactory;
    }

    public ConnectionBuilder connect() throws Exception {
        connection = null;
        try {
            connection = (HttpsURLConnection) url.openConnection();
            connection.setSSLSocketFactory(getSSLSocketFactory());
            connection.setConnectTimeout(5000);

            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            connection.setRequestMethod("POST");
            connection.setFixedLengthStreamingMode(parameters.getBytes().length);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (sessionId != null && !sessionId.isEmpty()) {
                connection.setRequestProperty("Session-Id", sessionId);
            }

            PrintWriter out = new PrintWriter(connection.getOutputStream());
            out.print(parameters);
            out.close();

            String response = "";
            Scanner inStream = new Scanner(connection.getInputStream());
            while (inStream.hasNextLine()) {
                response += inStream.nextLine();
            }
            this.response = response;

            return this;
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    public ConnectionBuilder context(Context context) {
        this.context = context;
        return this;
    }

    public ConnectionBuilder url(URL url) {
        this.url = url;
        return this;
    }

    public ConnectionBuilder url(String url) throws MalformedURLException {
        this.url = new URL(url);
        return this;
    }

    public ConnectionBuilder parameter(String parameter, String value) throws UnsupportedEncodingException {
        if (parameters.isEmpty()) {
            parameters = parameter + "=" + URLEncoder.encode(value, "UTF-8");
        } else {
            parameters += "&" + parameter + "=" + URLEncoder.encode(value, "UTF-8");
        }
        return this;
    }

    public String getResponse() {
        return response;
    }

    public String getHeader(String headerName) {
        return connection.getHeaderField(headerName);
    }

    public int getStatusCode() throws IOException{
        return connection.getResponseCode();
    }
}

在Android Activity中使用此类:

try {
    ConnectionBuilder cb = new ConnectionBuilder().context(getApplicationContext()).url(YOUR_URL).parameter("parameterName",parameterValue).parameter("anotherParameter",itsValue).connect();
    result = cb.getResponse();
    } catch (Exception e){
        e.printStackTrace();
    }

当然,您可以通过添加setHeader()功能来扩展此类。但在我的情况下,这不是必要的。