• Web支持HTTPS的client(HTTP&XML-RPC)


    生成Web自签名的证书(在命令行执行以下命令)

    keytool -genkey -keysize 2048 -validity 3650 -keyalg RSA -dname "CN=Hanshow, OU=Hanshow, O=Hanshow, L=Jiaxing, ST=Zhejiang, C=CN" -alias shopweb -keypass password_of_key -storepass password_of_store -keystore shopweb.jks

    -keysize 2048 指定生成2048位的密钥

    -validity 3650 指定证书有效期天数(3650=10年)

    -keyalg RSA 指定用RSA算法生成密钥

    -dname 设置签发者的信息

    -alias 设置别名

    -keypass 设定访问key的password

    -storepass 设定访问这个KeyStore的password

    web.jks指定生成的KeyStore文件名叫web.jks

    • 把生成的web.jks存放到classpath路径中。
    • 以下代码依赖Jackson JSON,OkHttp3,Apache XML-RPC Client。
    • 以下的实现全部是基于trustAll,即信任任何服务器

    基础SSL工具类SSLUtils

    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    
    public class SSLUtils {
        public static KeyStore loadKeyStore(String type, String fileName, String password) throws Exception {
            try (InputStream input = SSLUtils.class.getClassLoader().getResourceAsStream(fileName)) {
                if (input == null) {
                    throw new FileNotFoundException(String.format("cannot find KeyStore file "%s" in classpath",
                            fileName));
                }
    
                KeyStore ks = KeyStore.getInstance(type);
                ks.load(input, password.toCharArray());
                return ks;
            }
        }
    
        /**
         * 创建SSLSocketFactory
         *
         * @param protocol         SSL协议,默认:TLS
         * @param algorithm        KeyManager算法,默认:SunX509
         * @param provider         KeyManager提供者,默认:SunJSSE
         * @param keyPassword      Key password
         * @param keyStoreType     KeyStore类型,默认:JKS
         * @param keyStoreFileName KeyStore文件名,应在classpath中能找到。
         * @param storePassword    KeyStore的password
         * @return SSLSocketFactory实例
         * @throws Exception
         */
        public static SSLSocketFactory createSSLSocketFactory(String protocol, String algorithm, String provider, String keyPassword,
                                                              String keyStoreType, String keyStoreFileName, String storePassword) throws Exception {
    
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm, provider);
            KeyStore keyStore = loadKeyStore(keyStoreType, keyStoreFileName, storePassword);
            keyManagerFactory.init(keyStore, keyPassword.toCharArray());
    
            TrustManager[] trustManagers = new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }
    
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                            // Trust always
                        }
    
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                            // Trust always
                        }
                    }
            };
    
            SSLContext sslContext = SSLContext.getInstance(protocol);
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers,
                    new SecureRandom());
            return sslContext.getSocketFactory();
        }
    
        public static SSLSocketFactory createSSLSocketFactory(String keyPassword, String keyStoreFileName, String storePassword) throws Exception {
            return createSSLSocketFactory("TLS", "SunX509", "SunJSSE", keyPassword,
                    "JKS", keyStoreFileName, storePassword);
    
        }
    
        public static HostnameVerifier createHostnameVerifier() {
            return (hostname, session) -> true;
        }
    }
    

      XML-RPC Client

    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.apache.xmlrpc.client.XmlRpcClient;
    import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSocketFactory;
    import java.net.URL;
    
    public class DemoXmlRpcClient {
        private static boolean SSLContextInitialized = false;
    
        private URL url;
        private XmlRpcClient xmlRpcClient;
    
        public DemoXmlRpcClient(URL url) {
            this.url = url;
            if ("https".equalsIgnoreCase(url.getProtocol())) {
                initSSLContext();
            }
    
            XmlRpcClientConfigImpl rpcConfig = new XmlRpcClientConfigImpl();
            rpcConfig.setServerURL(this.url);
            // 设置RPC连接超时时间为60秒
            rpcConfig.setConnectionTimeout(60 * 1000);
            // 设置RPC等待响应时间为60秒
            rpcConfig.setReplyTimeout(60 * 1000);
            this.xmlRpcClient = new XmlRpcClient();
            this.xmlRpcClient.setConfig(rpcConfig);
        }
    
        private synchronized void initSSLContext() {
            if (!SSLContextInitialized) { // 只需要初始化一次
                try {
                    SSLSocketFactory sslSocketFactory = SSLUtils.createSSLSocketFactory(
                            "password_of_key", "shopweb.jks", "password_of_store");
                    HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
                    HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
                } catch (Throwable t) {
                    throw new RuntimeException("initialize SSLContext for XML-RPC error", t);
                }
                SSLContextInitialized = true;
            }
        }
    
        public Object execute(String command, Object[] params) throws Exception {
            return xmlRpcClient.execute(command, params);
        }
    
        public URL getUrl() {
            return url;
        }
    
        public static void main(String[] args) throws Exception {
            ObjectMapper objectMapper = new ObjectMapper();
            Object response;
    
            // 测试通过HTTPS向ESL-Working发送XML-RPC请求
            DemoXmlRpcClient sslClient = new DemoXmlRpcClient(new URL("https://127.0.0.1:9443/RPC2"));
            response = sslClient.execute("send_cmd", new Object[]{"API_VERSION", new Object[]{}});
            System.out.println(objectMapper.writeValueAsString(response));
    
            // 测试通过HTTP向ESL-Working发送XML-RPC请求
            DemoXmlRpcClient normalClient = new DemoXmlRpcClient(new URL("http://127.0.0.1:9000/RPC2"));
            response = normalClient.execute("send_cmd", new Object[]{"API_VERSION", new Object[]{}});
            System.out.println(objectMapper.writeValueAsString(response));
        }
    }
    

    HTTP Client

    import com.fasterxml.jackson.databind.ObjectMapper;
    import okhttp3.MediaType;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    import okhttp3.ResponseBody;
    import okhttp3.internal.platform.Platform;
    
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.X509TrustManager;
    import java.io.IOException;
    import java.net.URL;
    import java.util.concurrent.TimeUnit;
    
    public class DemoHttpClient {
        private final static String JSON_MEDIA_TYPE_PATTERN = "application/json; charset=%s";
        private final static String DEFAULT_CHARSET = "utf-8";
        private final static String DEFAULT_CONTENT_TYPE = String.format(JSON_MEDIA_TYPE_PATTERN, DEFAULT_CHARSET);
    
        private final static ObjectMapper objectMapper = new ObjectMapper();
        private OkHttpClient httpClient;
        private OkHttpClient httpsClient;
    
        public DemoHttpClient(String keyPassword, String fileName, String storePassword) throws Exception {
            httpClient = new OkHttpClient.Builder()
                    .readTimeout(60, TimeUnit.SECONDS)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS).build();
    
            SSLSocketFactory sslSocketFactory = SSLUtils.createSSLSocketFactory(keyPassword, fileName, storePassword);
            X509TrustManager x509TrustManager = Platform.get().trustManager(sslSocketFactory);
            httpsClient = new OkHttpClient.Builder()
                    .readTimeout(60, TimeUnit.SECONDS)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .sslSocketFactory(sslSocketFactory, x509TrustManager)
                    .hostnameVerifier(SSLUtils.createHostnameVerifier())
                    .build();
        }
    
        public String get(String url) throws IOException {
            return get(new URL(url));
        }
    
        public String get(URL url) throws IOException {
            return httpRequest(url, "GET", DEFAULT_CONTENT_TYPE, null);
        }
    
        public String post(String url, Object data) throws IOException {
            return post(new URL(url), data);
        }
    
        public String post(URL url, Object object) throws IOException {
            byte[] data = objectMapper.writeValueAsString(object).getBytes(DEFAULT_CHARSET);
            return httpRequest(url, "POST", DEFAULT_CONTENT_TYPE, data);
        }
    
        public String put(String url, Object data) throws IOException {
            return put(new URL(url), data);
        }
    
        public String put(URL url, Object object) throws IOException {
            byte[] data = objectMapper.writeValueAsString(object).getBytes(DEFAULT_CHARSET);
            return httpRequest(url, "PUT", DEFAULT_CONTENT_TYPE, data);
        }
    
        public String httpRequest(URL url, String method, String contentType, byte[] data) throws IOException {
            OkHttpClient client;
            String protocol = url.getProtocol();
            if ("http".equalsIgnoreCase(protocol)) {
                client = httpClient;
            } else if ("https".equalsIgnoreCase(protocol)) {
                client = httpsClient;
            } else {
                throw new UnsupportedOperationException("unsupported protocol: " + protocol);
            }
    
            Request.Builder builder = new Request.Builder().url(url);
            MediaType mediaType = MediaType.parse(contentType);
            if ("GET".equalsIgnoreCase(method)) {
                builder.get();
            } else {
                RequestBody requestBody = RequestBody.create(mediaType, data == null ? new byte[0] : data);
                builder.method(method, requestBody);
            }
    
            Request request = builder.build();
            try (Response response = client.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    ResponseBody responseBody = response.body();
                    return responseBody == null ? null : responseBody.string();
                } else {
                    throw new IOException(String.format(
                            "%s/%s %s got unexpected response code %d",
                            protocol.toUpperCase(), method, url, response.code()));
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            DemoHttpClient httpClient = new DemoHttpClient("password_of_key", "shopweb.jks", "password_of_store");
    
            // 通过HTTP访问ESL-Working RESTful接口
            System.out.println(httpClient.get("http://127.0.0.1:9000/api2/runinfo"));
    
            // 通过HTTPS访问ESL-Working RESTful接口
            System.out.println(httpClient.get("https://127.0.0.1:9443/api2/runinfo"));
        }
    }
    

      

  • 相关阅读:
    Bootstrap的介绍和响应式媒体查询
    jquery内容补充
    jquery的ajax
    jquery的事件
    JQuery的筛选方法
    jquery的css
    jQuery的文档操作
    操作表单域中的value值
    jquery的属性操作
    jquery的效果
  • 原文地址:https://www.cnblogs.com/fan-yuan/p/11284816.html
Copyright © 2020-2023  润新知