zoukankan      html  css  js  c++  java
  • java访问Https服务的客户端示例

    关于证书

    1、每个人都可以使用一些证书生成工具为自己的https站点生成证书(比如JDK的keytool),大家称它为“自签名证书”,但是自己生成的证书是不被浏览器承认的,所以浏览器会报安全提示,要求你手动安装证书,提示风险,是否继续等。只有通过权威的CA机构付费获得的证书才能被浏览器承认。

    2、证书(无客户端服务端之分)保存着IP信息、证书过期时间、证书所有者地址信息等。

    双向认证

    1、先决条件是有两个或两个以上的证书,一个是服务端证书,另一个或多个是客户端证书。

    2、服务端保存着客户端的证书并信任该证书,客户端保存着服务端的证书并信任该证书。这样,在证书验证成功的情况下即可完成请求响应。

    3、双向认证安全性更高。

    单向认证

    1、客户端保存着服务端的证书并信任该证书即可。

    2、https一般是单向认证,这样可以让绝大部分人可以访问你的站点。

    使用示例代码:

    public interface PCIHttpClient {
    
        /** 请求头信息:Content-Type **/
        public static final String CONTENT_TYPE = "Content-Type";
        /** 请求头信息:User-Agent **/
        public static final String USER_AGENT = "User-Agent";
        /** 默认的内容类型 **/
        public static final String DEFAULT_CONTENTTYPE = "application/x-www-form-urlencoded;charset=UTF-8";
        /** 默认的用户代理(浏览器类型) **/
        public static final String DEFAULT_USERAGENT = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; InfoPath.1; .NET CLR 1.1.4322; CIBA)";
        /** 默认的读取超时时间(单位毫秒) **/
        public static final int DEFAULT_TIMEOUT = 180000;
        /** 默认的连接超时时间(单位毫秒) **/
        public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendGetAndResponseAsString(String url, 
                int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendGetAndResponseAsString(String url, 
                Map<String, String> headers, int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendGetAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendGetAndResponseAsByteArray(String url, 
                int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendGetAndResponseAsByteArray(String url, 
                Map<String, String> headers, int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendGetAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException;
    
        /**
         * 发送GET方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(输入流)
         * @throws IOException
         */
        public InputStream sendGetAndResponseAsStream(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException;
    
        /**
         * 发送GET方式请求
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @param output 响应内容(输出流)
         * @throws IOException
         */
        public void sendGet(String url, Map<String, String> headers, 
                Map<String, String> params, String charsetName, int timeout, 
                OutputStream output) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> params, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param timeout 超时时间(单位毫秒)
         * @param charsetName 字符编码
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                int timeout, String charsetName) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Object stringOrStream, 
                String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字符串)
         * @throws IOException
         */
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> params, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param timeout 超时时间(单位毫秒)
         * @param charsetName 字符编码
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                int timeout, String charsetName) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Object stringOrStream, 
                String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(字节数组)
         * @throws IOException
         */
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求数据,并接收响应数据
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return 响应内容(输入流)
         * @throws IOException
         */
        public InputStream sendPostAndResponseAsStream(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @param output 响应内容(输出流)
         * @throws IOException
         */
        public void sendPost(String url, Map<String, String> headers, 
                Map<String, String> params, Object stringOrStream, 
                String charsetName, int timeout, OutputStream output) throws IOException;
    
        /**
         * 发送GET方式请求
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return
         * @throws IOException
         * 
         * @since 2.0.0
         */
        public PCIHttpResponse sendGet(String url, Map<String, String> headers, 
                Map<String, String> params, String charsetName, int timeout) throws IOException;
    
        /**
         * 发送POST方式请求
         * 
         * @param url 请求地址
         * @param headers 请求头信息
         * @param params 请求参数
         * @param stringOrStream 请求体内容(字符串或者输入流)
         * @param charsetName 字符编码
         * @param timeout 超时时间(单位毫秒)
         * @return
         * @throws IOException
         * 
         * @since 2.0.0
         */
        public PCIHttpResponse sendPost(String url, Map<String, String> headers, 
                Map<String, String> params, Object stringOrStream, 
                String charsetName, int timeout) throws IOException;
    
    }
    public class CustomConstants {
    
        /** 字符编码:UTF-8 */
        public static final String CHARSET_UTF8 = "UTF-8";
    
    }
    public class CustomStringUtils {
    
        private static LogUtils logger = new LogUtils(CustomStringUtils.class);
    
        /**
         * 长度不足,左补字符
         * @param str
         * @param ch
         * @param len
         * @return
         */
        public static String leftFill(String str, char ch, int len) {
            if (str == null) {
                str = "";
            }
            while (str.length() < len) {
                str = ch + str;
            }
            return str;
        }
    
        /**
         * 长度不足,右补字符
         * @param str
         * @param ch
         * @param len
         * @return
         */
        public static String rightFill(String str, char ch, int len) {
            if (str == null) {
                str = "";
            }
            while (str.length() < len) {
                str = str + ch;
            }
            return str;
        }
    
        /**
         * 拼接字符串
         * @param objs
         * @return
         */
        public static String append(Object... objs) {
            if (objs == null || objs.length == 0) {
                return "";
            }
            StringBuffer buffer = new StringBuffer();
            for (Object obj : objs) {
                buffer.append(obj);
            }
            return buffer.toString();
        }
    
        /**
         * 如果字符串为空,则返回空字符
         * @param str
         * @return
         */
        public static String nullToBlank(String str) {
            return str == null ? "" : str;
        }
    
        /**
         * 将map转化成字符串
         * @param map
         * @return 格式:key1=value1&key2=value2...
         */
        public static String convertMapToString(Map<String, String> map) {
            if (map == null || map.isEmpty()) {
                return null;
            }
            StringBuffer buffer = new StringBuffer();
            boolean first = true;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (first) {
                    buffer.append(entry.getKey()).append("=").append(entry.getValue());
                    first = false;
                } else {
                    buffer.append("&").append(entry.getKey()).append("=").append(entry.getValue());
                }
            }
            return buffer.toString();
        }
    
        /**
         * 将map转化成字符串,并对map.value进行URL编码
         * @param map
         * @param encoding
         * @return 格式:key1=value1&key2=value2...
         */
        public static String convertMapToString(Map<String, String> map, String encoding) {
            if (map == null || map.isEmpty()) {
                return null;
            }
            StringBuffer buffer = new StringBuffer();
            boolean first = true;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (first) {
                    buffer.append(entry.getKey()).append("=").append(urlEncode(entry.getValue(), encoding));
                    first = false;
                } else {
                    buffer.append("&").append(entry.getKey()).append("=").append(urlEncode(entry.getValue(), encoding));
                }
            }
            return buffer.toString();
        }
    
        /**
         * 将map转化成字符串(当参数值为null时,则忽略该参数)
         * @param map
         * @return 格式:key1=value1&key2=value2...
         */
        public static String convertMapToStringIgnoreNull(Map<String, String> map) {
            if (map == null || map.isEmpty()) {
                return null;
            }
            StringBuffer buffer = new StringBuffer();
            boolean first = true;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                if (first) {
                    buffer.append(entry.getKey()).append("=").append(entry.getValue());
                    first = false;
                } else {
                    buffer.append("&").append(entry.getKey()).append("=").append(entry.getValue());
                }
            }
            return buffer.toString();
        }
    
        /**
         * 将map转化成字符串,并对map.value进行URL编码(当参数值为null时,则忽略该参数)
         * @param map
         * @param encoding
         * @return 格式:key1=value1&key2=value2...
         */
        public static String convertMapToStringIgnoreNull(Map<String, String> map, String encoding) {
            if (map == null || map.isEmpty()) {
                return null;
            }
            StringBuffer buffer = new StringBuffer();
            boolean first = true;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                if (first) {
                    buffer.append(entry.getKey()).append("=").append(urlEncode(entry.getValue(), encoding));
                    first = false;
                } else {
                    buffer.append("&").append(entry.getKey()).append("=").append(urlEncode(entry.getValue(), encoding));
                }
            }
            return buffer.toString();
        }
    
        /**
         * 对字符串进行URL编码
         * @param str
         * @param encoding
         * @return
         */
        public static String urlEncode(String str, String encoding) {
            if (str == null || "".equals(str)) {
                return str;
            }
            try {
                return URLEncoder.encode(str, encoding);
            } catch (UnsupportedEncodingException e) {
                logger.error(append("URL encode string error. str=", str, ", encoding=", encoding), e);
                return str;
            }
        }
    
        /**
         * 对字符串进行URL解码
         * @param str
         * @param encoding
         * @return
         */
        public static String urlDecode(String str, String encoding) {
            if (str == null || "".equals(str)) {
                return str;
            }
            try {
                return URLDecoder.decode(str, encoding);
            } catch (UnsupportedEncodingException e) {
                logger.error(append("URL decode string error. str=", str, ", encoding=", encoding), e);
                return str;
            }
        }
    
        /**
         * 字符串的字节长度是否超出边界值
         * @param str 字符串
         * @param bounds 边界值
         * @param charsetName 字符编码
         * @return
         */
        public static boolean bytesLengthOutOfBounds(
                String str, int bounds, String charsetName) {
            if (bounds < 0 || str == null || "".equals(str)) {
                return false;
            }
            try {
                int bytesLen = str.getBytes(charsetName).length;
                return bytesLen > bounds;
            } catch (UnsupportedEncodingException e) {
                logger.error(append("Check bytes length out of bounds error. str=", 
                        str, ", charsetName=", charsetName), e);
            }
            return false;
        }
    
        /**
         * @Title: generate 
         * @Description: 随机生成指定长度的16进制的字符串
         * @since: 0.0.1
         * @param len    字符串长度
         * @return
         */
        public static String generateRandomHex(int len){
            
            if (len < 1) {
                return null;
            }
            
            StringBuffer sb = new StringBuffer();
            Random random = new Random();
            
            for (int i = 0; i < len; i++) {
                sb.append(Integer.toHexString(random.nextInt(16)));
            }
            
            return sb.toString().toUpperCase();
        }
        
        /**
         * @Title: generateConformOddCheckHex 
         * @Description: 生成符合奇校验的字符串
         * @since: 0.0.1    
         * @param len    字节长度
         * @return
         */
        public static String generateConformOddCheckHex(int len) {
            
            byte[] bytes = new byte[len];
            for (int i = 0; i < len; i++) {
                Random random = new Random();
                int randomInt = random.nextInt(255);
                String binaryString = Integer.toBinaryString(randomInt);
                boolean oddCheck = isConformOddCheck(binaryString);
                if (!oddCheck) {
                    randomInt ^= 1;
                }
    //            System.err.println(Integer.toBinaryString(randomInt));
                byte b = (byte) randomInt;
                bytes[i] = b;
            } 
            String hexString = CommonUtils.byte2hexString(bytes);
            return hexString;
        }
        
        /**
         * @Title: oddCheck 
         * @Description: 检验是否符合奇校验
         * @since: 0.0.1
         * @param binaryString
         * @return
         */
        private static boolean isConformOddCheck(String binaryString) {
            int sum = 0;
            char[] charArray = binaryString.toCharArray();
            for(char c : charArray){
                if (c == '1') {
                    sum ++;
                }
            }
            if (sum%2 == 1) {
                return true;
            }
            return false;
        }
        
    }
    public class IOUtils {
    
        private static LogUtils logger = new LogUtils(IOUtils.class);
        
        /** 默认的缓冲区大小 **/
        private static final int DEFAULT_BUFFER_SIZE = 4096;
    
        /**
         * 将字节输入流转换成字节数组
         * @param input
         * @return
         * @throws IOException
         */
        public static byte[] toByteArray(InputStream input) throws IOException {
            ByteArrayOutputStream output = null;
            try {
                output = new ByteArrayOutputStream();
                copy(input, output);
                return output.toByteArray();
            } finally {
                closeQuietly(output);
            }
        }
    
        /**
         * 将字符输入流转换成字节数组
         * @param reader
         * @return
         * @throws IOException
         */
        public static byte[] toByteArray(Reader reader) throws IOException {
            ByteArrayOutputStream output = null;
            try {
                output = new ByteArrayOutputStream();
                copy(reader, output);
                return output.toByteArray();
            } finally {
                closeQuietly(output);
            }
        }
    
        /**
         * 将字符输入流转换成字节数组
         * @param reader
         * @param encoding
         * @return
         * @throws IOException
         */
        public static byte[] toByteArray(Reader reader, String encoding) throws IOException {
            ByteArrayOutputStream output = null;
            try {
                output = new ByteArrayOutputStream();
                copy(reader, output, encoding);
                return output.toByteArray();
            } finally {
                closeQuietly(output);
            }
        }
    
        /**
         * 将字节输入流转换成字符串
         * @param input
         * @return
         * @throws IOException
         */
        public static String toString(InputStream input) throws IOException {
            StringWriter writer = null;
            try {
                writer = new StringWriter();
                copy(input, writer);
                return writer.toString();
            } finally {
                closeQuietly(writer);
            }
        }
    
        /**
         * 将字节输入流转换成字符串
         * @param input
         * @param encoding
         * @return
         * @throws IOException
         */
        public static String toString(InputStream input, String encoding) throws IOException {
            StringWriter writer = null;
            try {
                writer = new StringWriter();
                copy(input, writer, encoding);
                return writer.toString();
            } finally {
                closeQuietly(writer);
            }
        }
    
        /**
         * 将字符输入流转换成字符串
         * @param reader
         * @return
         * @throws IOException
         */
        public static String toString(Reader reader) throws IOException {
            StringWriter writer = null;
            try {
                writer = new StringWriter();
                copy(reader, writer);
                return writer.toString();
            } finally {
                closeQuietly(writer);
            }
        }
    
        /**
         * 按行读取字节输入流
         * @param input
         * @return
         * @throws IOException
         */
        public static List<String> readLines(InputStream input) throws IOException {
    //        InputStreamReader reader = new InputStreamReader(input);
    //        return readLines(reader);
            InputStreamReader reader = null;
            try {
                reader = new InputStreamReader(input);
                return readLines(reader);
            } finally {
                closeQuietly(reader);
            }
        }
    
        /**
         * 按行读取字节输入流
         * @param input
         * @param encoding
         * @return
         * @throws IOException
         */
        public static List<String> readLines(InputStream input, String encoding) throws IOException {
    //        if (encoding == null) {
    //            return readLines(input);
    //        }
    //        InputStreamReader reader = new InputStreamReader(input, encoding);
    //        return readLines(reader);
            if (encoding == null) {
                return readLines(input);
            }
            InputStreamReader reader = null;
            try {
                reader = new InputStreamReader(input, encoding);
                return readLines(reader);
            } finally {
                closeQuietly(reader);
            }
        }
    
        /**
         * 按行读取字符输入流
         * @param reader
         * @return
         * @throws IOException
         */
        public static List<String> readLines(Reader reader) throws IOException {
    //        BufferedReader br = new BufferedReader(reader);
    //        List<String> lines = new ArrayList<String>();
    //        String line = br.readLine();
    //        while (line != null) {
    //            lines.add(line);
    //            line = br.readLine();
    //        }
    //        return lines;
            BufferedReader br = null;
            try {
                br = new BufferedReader(reader);
                List<String> lines = new ArrayList<String>();
                String line = br.readLine();
                while (line != null) {
                    lines.add(line);
                    line = br.readLine();
                }
                return lines;
            } finally {
                closeQuietly(br);
            }
        }
    
        /**
         * 阻塞地读取字节输入流
         * @param input
         * @param buffer
         * @param off
         * @param length
         * @throws IOException
         */
        public static void read(InputStream input, 
                byte[] buffer, int off, int length) throws IOException {
            while (off < length) {
                off = off + input.read(buffer, off, length - off);
                if (off < 0) {
                    throw new IOException("读取时出错[readLen=" + off + "]");
                }
            }
        }
    
        /**
         * 将字节输入流拷贝到字符输出流
         * @param input
         * @param writer
         * @throws IOException
         */
        public static void copy(InputStream input, Writer writer) throws IOException {
    //        InputStreamReader reader = new InputStreamReader(input);
    //        copy(reader, writer);
            InputStreamReader reader = null;
            try {
                reader = new InputStreamReader(input);
                copy(reader, writer);
            } finally {
                closeQuietly(reader);
            }
        }
    
        /**
         * 将字节输入流拷贝到字符输出流
         * @param input
         * @param writer
         * @param encoding
         * @throws IOException
         */
        public static void copy(InputStream input, Writer writer, String encoding) throws IOException {
    //        if (encoding == null) {
    //            copy(input, writer);
    //        } else {
    //            InputStreamReader reader = new InputStreamReader(input, encoding);
    //            copy(reader, writer);
    //        }
            if (encoding == null) {
                copy(input, writer);
            } else {
                InputStreamReader reader = null;
                try {
                    reader = new InputStreamReader(input, encoding);
                    copy(reader, writer);
                } finally {
                    closeQuietly(reader);
                }
            }
        }
    
        /**
         * 将字节输入流拷贝到字节输出流
         * @param input
         * @param output
         * @return 字节数
         * @throws IOException
         */
        public static int copy(InputStream input, OutputStream output) throws IOException {
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int count = 0;
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
                count += n;
            }
            output.flush();
            return count;
        }
    
        /**
         * 将字符输入流拷贝到字节输出流
         * @param reader
         * @param output
         * @throws IOException
         */
        public static void copy(Reader reader, OutputStream output) throws IOException {
    //        OutputStreamWriter writer = new OutputStreamWriter(output);
    //        copy(reader, writer);
            OutputStreamWriter writer = null;
            try {
                writer = new OutputStreamWriter(output);
                copy(reader, writer);
            } finally {
                closeQuietly(writer);
            }
        }
    
        /**
         * 将字符输入流拷贝到字节输出流
         * @param reader
         * @param output
         * @param encoding
         * @throws IOException
         */
        public static void copy(Reader reader, OutputStream output, String encoding)
                throws IOException {
    //        if (encoding == null) {
    //            copy(reader, output);
    //        } else {
    //            OutputStreamWriter writer = new OutputStreamWriter(output, encoding);
    //            copy(reader, writer);
    //        }
            if (encoding == null) {
                copy(reader, output);
            } else {
                OutputStreamWriter writer = null;
                try {
                    writer = new OutputStreamWriter(output, encoding);
                    copy(reader, writer);
                } finally {
                    closeQuietly(writer);
                }
            }
        }
    
        /**
         * 将字符输入流拷贝到字符输出流
         * @param reader
         * @param writer
         * @return 字符数
         * @throws IOException
         */
        public static int copy(Reader reader, Writer writer) throws IOException {
            char[] buffer = new char[DEFAULT_BUFFER_SIZE];
            int count = 0;
            int n = 0;
            while (-1 != (n = reader.read(buffer))) {
                writer.write(buffer, 0, n);
                count += n;
            }
            writer.flush();
            return count;
        }
    
        /**
         * 关闭IO流
         * @param close
         */
        public static void closeQuietly(Closeable close) {
            closeQuietly(close, "关闭IO流出错!");
        }
    
        /**
         * 关闭IO流
         * @param close
         * @param errorMsg
         */
        public static void closeQuietly(Closeable close, String errorMsg) {
            if (close != null) {
                try {
                    close.close();
                } catch (IOException e) {
                    logger.error(errorMsg, e);
                }
            }
        }
    public class PCIHttpClientImpl4 implements PCIHttpClient {
    
        private static LogUtils logger = new LogUtils(PCIHttpClientImpl4.class);
        
        private SSLConnectionSocketFactory sslSocketFactory = null;
    
        /**
         * 构造方法
         * 
         * <p>允许信任任何证书策略和允许任何域名验证</p>
         */
        public PCIHttpClientImpl4() {
            this(false, false, true, true, null, null, null);
        }
    
        /**
         * 构造方法
         * 
         * @param allowAnyTrustMaterial 是否允许信任任何证书策略
         * @param allowAnyHostnameVerifier 是否允许任何域名验证
         */
        public PCIHttpClientImpl4(boolean allowAnyTrustMaterial, boolean allowAnyHostnameVerifier) {
            this(false, false, allowAnyTrustMaterial, allowAnyHostnameVerifier, null, null, null);
        }
    
        /**
         * 构造方法
         * 
         * @param loadKeyMaterial 是否加载密钥
         * @param loadTrustMaterial 是否加载信任证书
         * @param keystoreFilePath 密钥库文件路径
         * @param storePassword 密钥库密码
         * @param keyPassword 私钥密码
         */
        public PCIHttpClientImpl4(boolean loadKeyMaterial, boolean loadTrustMaterial, 
                String keystoreFilePath, String storePassword, String keyPassword) {
            this(loadKeyMaterial, loadTrustMaterial, false, true, keystoreFilePath, storePassword, keyPassword);
        }
    
        /**
         * 构造方法
         * 
         * @param loadKeyMaterial 是否加载密钥
         * @param loadTrustMaterial 是否加载信任证书(若allowAnyTrustMaterial=true,则loadTrustMaterial无效)
         * @param allowAnyTrustMaterial 是否允许信任任何证书策略
         * @param allowAnyHostnameVerifier 是否允许任何域名验证
         * @param keystoreFilePath 密钥库文件路径
         * @param storePassword 密钥库密码
         * @param keyPassword 私钥密码
         */
        public PCIHttpClientImpl4(boolean loadKeyMaterial, boolean loadTrustMaterial, 
                boolean allowAnyTrustMaterial, boolean allowAnyHostnameVerifier, 
                String keystoreFilePath, String storePassword, String keyPassword) {
            try {
                // Create SSLContext
                SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
                if (loadKeyMaterial) {
                    sslContextBuilder.loadKeyMaterial(
                            new File(keystoreFilePath), storePassword.toCharArray(), keyPassword.toCharArray());
                }
                if (allowAnyTrustMaterial) {
                    sslContextBuilder.loadTrustMaterial(null, new AnyTrustStrategy());
                } else if (loadTrustMaterial) {
                    sslContextBuilder.loadTrustMaterial(
                            new File(keystoreFilePath), storePassword.toCharArray(), new TrustSelfSignedStrategy());
                }
                SSLContext sslContext = sslContextBuilder.build();
                
                // Create SSLConnectionSocketFactory
                if (allowAnyHostnameVerifier) {
                    sslSocketFactory = new SSLConnectionSocketFactory(sslContext, new AnyHostnameVerifier());
                } else {
                    sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
                }
            } catch (NoSuchAlgorithmException e) {
                logger.error("Error occurred: NoSuchAlgorithmException", e);
            } catch (KeyStoreException e) {
                logger.error("Error occurred: KeyStoreException", e);
            } catch (UnrecoverableKeyException e) {
                logger.error("Error occurred: UnrecoverableKeyException", e);
            } catch (CertificateException e) {
                logger.error("Error occurred: CertificateException", e);
            } catch (IOException e) {
                logger.error("Error occurred: IOException", e);
            } catch (KeyManagementException e) {
                logger.error("Error occurred: KeyManagementException", e);
            }
        }
    
        /**
         * 信任任何证书策略
         */
        private static class AnyTrustStrategy implements TrustStrategy {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                return true;
            }
        }
    
        /**
         * 允许任何域名验证
         */
        private static class AnyHostnameVerifier implements HostnameVerifier {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        }
    
        @Override
        public String sendGetAndResponseAsString(String url, 
                int timeout) throws IOException {
            return sendGetAndResponseAsString(url, null, null, CustomConstants.CHARSET_UTF8, timeout);
        }
    
        @Override
        public String sendGetAndResponseAsString(String url, 
                Map<String, String> headers, int timeout) throws IOException {
            return sendGetAndResponseAsString(url, headers, null, CustomConstants.CHARSET_UTF8, timeout);
        }
    
        @Override
        public String sendGetAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException {
            byte[] buffer = sendGetAndResponseAsByteArray(url, headers, params, charsetName, timeout);
            if (buffer == null) {
                return null;
            }
            return new String(buffer, charsetName);
        }
    
        @Override
        public byte[] sendGetAndResponseAsByteArray(String url, 
                int timeout) throws IOException {
            return sendGetAndResponseAsByteArray(url, null, null, null, timeout);
        }
    
        @Override
        public byte[] sendGetAndResponseAsByteArray(String url, 
                Map<String, String> headers, int timeout) throws IOException {
            return sendGetAndResponseAsByteArray(url, headers, null, null, timeout);
        }
    
        @Override
        public byte[] sendGetAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException {
            ByteArrayOutputStream output = null;
            try {
                output = new ByteArrayOutputStream();
                sendGet(url, headers, params, charsetName, timeout, output);
                return output.toByteArray();
            } finally {
                IOUtils.closeQuietly(output);
            }
        }
    
        @Override
        public InputStream sendGetAndResponseAsStream(String url, 
                Map<String, String> headers, Map<String, String> params, 
                String charsetName, int timeout) throws IOException {
            byte[] buffer = sendGetAndResponseAsByteArray(url, headers, params, charsetName, timeout);
            if (buffer == null) {
                return null;
            }
            return new ByteArrayInputStream(buffer);
        }
    
        @Override
        public void sendGet(String url, Map<String, String> headers, 
                Map<String, String> params, String charsetName, int timeout, 
                OutputStream output) throws IOException {
            if (StringUtils.isEmpty(url)) {
                logger.error("The url can not be null.");
                throw new IllegalArgumentException("The url can not be null.");
            }
            sendAndResponseAsStream(new HttpGet(createURI(url, params, charsetName)), 
                    headers, timeout, output);
        }
    
        @Override
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> params, String charsetName, int timeout) throws IOException {
            return sendPostAndResponseAsString(url, null, params, null, charsetName, timeout);
        }
    
        @Override
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                int timeout, String charsetName) throws IOException {
            return sendPostAndResponseAsString(url, headers, params, null, charsetName, timeout);
        }
    
        @Override
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Object stringOrStream, 
                String charsetName, int timeout) throws IOException {
            return sendPostAndResponseAsString(url, headers, null, stringOrStream, charsetName, timeout);
        }
    
        @Override
        public String sendPostAndResponseAsString(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException {
            byte[] buffer = sendPostAndResponseAsByteArray(
                    url, headers, params, stringOrStream, charsetName, timeout);
            if (buffer == null) {
                return null;
            }
            return new String(buffer, charsetName);
        }
    
        @Override
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> params, String charsetName, int timeout) throws IOException {
            return sendPostAndResponseAsByteArray(url, null, params, null, charsetName, timeout);
        }
    
        @Override
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                int timeout, String charsetName) throws IOException {
            return sendPostAndResponseAsByteArray(url, headers, params, null, charsetName, timeout);
        }
    
        @Override
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Object stringOrStream, 
                String charsetName, int timeout) throws IOException {
            return sendPostAndResponseAsByteArray(url, headers, null, stringOrStream, charsetName, timeout);
        }
    
        @Override
        public byte[] sendPostAndResponseAsByteArray(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException {
            ByteArrayOutputStream output = null;
            try {
                output = new ByteArrayOutputStream();
                sendPost(url, headers, params, stringOrStream, charsetName, timeout, output);
                return output.toByteArray();
            } finally {
                IOUtils.closeQuietly(output);
            }
        }
    
        @Override
        public InputStream sendPostAndResponseAsStream(String url, 
                Map<String, String> headers, Map<String, String> params, 
                Object stringOrStream, String charsetName, int timeout) throws IOException {
            byte[] buffer = sendPostAndResponseAsByteArray(
                    url, headers, params, stringOrStream, charsetName, timeout);
            if (buffer == null) {
                return null;
            }
            return new ByteArrayInputStream(buffer);
        }
    
        @Override
        public void sendPost(String url, Map<String, String> headers, 
                Map<String, String> params, Object stringOrStream, 
                String charsetName, int timeout, OutputStream output) throws IOException {
            if (StringUtils.isEmpty(url)) {
                logger.error("The url can not be null.");
                throw new IllegalArgumentException("The url can not be null.");
            }
            
            // post请求方式
            HttpPost method = new HttpPost(createURI(url, params, charsetName));
            
            // 设置请求头信息
            if (headers == null) {
                headers = new HashMap<String, String>();
            }
            if (!headers.containsKey(CONTENT_TYPE)) {
                headers.put(CONTENT_TYPE, DEFAULT_CONTENTTYPE);
            }
            
            // 设置请求体内容
            if (stringOrStream != null) {
                HttpEntity entity = null;
                if (stringOrStream instanceof InputStream) {
                    entity = new InputStreamEntity((InputStream) stringOrStream);
                } else {
                    entity = new StringEntity(stringOrStream.toString(), 
                            ContentType.create(CONTENT_TYPE, charsetName));
                }
                method.setEntity(entity);
            }
            
            // 发送请求数据,并接收响应数据
            sendAndResponseAsStream(method, headers, timeout, output);
        }
    
        /**
         * 发送请求数据,并接收响应数据
         * @param method 请求方式
         * @param headers 请求头信息
         * @param timeout 超时时间
         * @param output 响应内容(输出流)
         * @throws IOException
         */
        private void sendAndResponseAsStream(HttpRequestBase method, 
                Map<String, String> headers, int timeout, OutputStream output) throws IOException {
            // 设置请求配置信息
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT) //连接超时时间
                    .setSocketTimeout(timeout) //读取超时时间
                    .setCircularRedirectsAllowed(true) //设置是否允许循环重定向(重定向到相同路径)
                    .build();
            method.setConfig(config);
            
            // 设置请求头信息
            if (headers == null) {
                headers = new HashMap<String, String>();
            }
            if (!headers.containsKey(USER_AGENT)) {
                headers.put(USER_AGENT, DEFAULT_USERAGENT);
            }
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                method.setHeader(entry.getKey(), entry.getValue());
            }
            
            // 发送请求
            CloseableHttpClient httpClient = createHttpClient(method.getURI());
            CloseableHttpResponse httpResponse = null;
            InputStream input = null;
            try {
                httpResponse = httpClient.execute(method);
                int status = httpResponse.getStatusLine().getStatusCode();
                if (status != HttpStatus.SC_OK) {
                    String errorMsg = CustomStringUtils.append("The remote service[", 
                            method.getURI(), "] respose an error status:", status);
                    logger.error(errorMsg);
                    if (status >= 500 && status < 600) {
                        throw new IOException(errorMsg);
                    }
                }
                HttpEntity httpEntity = httpResponse.getEntity();
                if (httpEntity == null) {
                    String errorMsg = CustomStringUtils.append("The remote service[", 
                            method.getURI(), "] respose entity is null. status:", status);
                    logger.error(errorMsg);
                    throw new IOException(errorMsg);
                }
                input = httpEntity.getContent();
                if (input == null) {
                    String errorMsg = CustomStringUtils.append("The remote service[", 
                            method.getURI(), "] respose entity content is null. status:", status);
                    logger.error(errorMsg);
                    throw new IOException(errorMsg);
                }
                IOUtils.copy(input, output);
            } catch (IOException e) {
                logger.error("Access to the remote service[" + method.getURI() + "] error.", e);
                throw e;
            } finally {
                IOUtils.closeQuietly(input);
    //            method.releaseConnection();
                IOUtils.closeQuietly(httpResponse);
                IOUtils.closeQuietly(httpClient);
            }
        }
    
        /**
         * 创建HttpClient对象
         * @param uri
         * @return
         */
        private CloseableHttpClient createHttpClient(URI uri) {
            if ("https".equalsIgnoreCase(uri.getScheme()) && sslSocketFactory != null) {
                return HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
            } else {
                return HttpClients.createDefault();
            }
        }
    
        /**
         * 创建请求URI
         * @param url
         * @param params
         * @param charsetName
         * @return
         * @throws IOException
         */
        private URI createURI(String url, 
                Map<String, String> params, String charsetName) throws IOException {
            if (params == null || params.isEmpty()) {
                return URI.create(url);
            }
            // 设置请求参数
            List<NameValuePair> parameters = new ArrayList<NameValuePair>(params.size());
            for (Map.Entry<String, String> entry : params.entrySet()) {
                parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            try {
                return new URIBuilder(url)
                    .addParameters(parameters)
                    .setCharset(Charset.forName(charsetName))
                    .build();
            } catch (URISyntaxException e) {
                String errorMsg = "Build request URI error, the url is [" + url + "].";
                logger.error(errorMsg, e);
                throw new IOException(errorMsg, e);
            }
        }
    
        /** 
         * @see PCIHttpClient.com.bestpay.pgw.tools.http.PGWHttpClient#sendGet(java.lang.String, java.util.Map, java.util.Map, java.lang.String, int)
         */
        @Override
        public PCIHttpResponse sendGet(String url, Map<String, String> headers,
                Map<String, String> params, String charsetName, int timeout)
                throws IOException {
            if (StringUtils.isEmpty(url)) {
                logger.error("The url can not be null.");
                throw new IllegalArgumentException("The url can not be null.");
            }
            return sendAndResponseAsStream(
                    new HttpGet(createURI(url, params, charsetName)), headers, timeout);
        }
    
        /** 
         * @see PCIHttpClient.com.bestpay.pgw.tools.http.PGWHttpClient#sendPost(java.lang.String, java.util.Map, java.util.Map, java.lang.Object, java.lang.String, int)
         */
        @Override
        public PCIHttpResponse sendPost(String url, Map<String, String> headers,
                Map<String, String> params, Object stringOrStream,
                String charsetName, int timeout) throws IOException {
            if (StringUtils.isEmpty(url)) {
                logger.error("The url can not be null.");
                throw new IllegalArgumentException("The url can not be null.");
            }
            
            // post请求方式
            HttpPost method = new HttpPost(createURI(url, params, charsetName));
            
            // 设置请求头信息
            if (headers == null) {
                headers = new HashMap<String, String>();
            }
            if (!headers.containsKey(CONTENT_TYPE)) {
                headers.put(CONTENT_TYPE, DEFAULT_CONTENTTYPE);
            }
            
            // 设置请求体内容
            if (stringOrStream != null) {
                HttpEntity entity = null;
                if (stringOrStream instanceof InputStream) {
                    entity = new InputStreamEntity((InputStream) stringOrStream);
                } else {
                    entity = new StringEntity(stringOrStream.toString(), 
                            ContentType.create(CONTENT_TYPE, charsetName));
                }
                method.setEntity(entity);
            }
            
            // 发送请求数据,并接收响应数据
            return sendAndResponseAsStream(method, headers, timeout);
        }
    
        /**
         * 发送请求数据,并接收响应数据
         * 
         * @param method 请求方式
         * @param headers 请求头信息
         * @param timeout 超时时间
         * @return
         * @throws IOException
         * 
         * @since 2.0.0
         */
        private PCIHttpResponse sendAndResponseAsStream(HttpRequestBase method, 
                Map<String, String> headers, int timeout) throws IOException {
            // 设置请求配置信息
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT) //连接超时时间
                    .setSocketTimeout(timeout) //读取超时时间
                    .setCircularRedirectsAllowed(true) //设置是否允许循环重定向(重定向到相同路径)
                    .build();
            method.setConfig(config);
            
            // 设置请求头信息
            if (headers == null) {
                headers = new HashMap<String, String>();
            }
            if (!headers.containsKey(USER_AGENT)) {
                headers.put(USER_AGENT, DEFAULT_USERAGENT);
            }
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                method.setHeader(entry.getKey(), entry.getValue());
            }
            
            // 发送请求
            CloseableHttpClient httpClient = createHttpClient(method.getURI());
            CloseableHttpResponse httpResponse = null;
            InputStream responseBodyInputStream = null;
            ByteArrayOutputStream responseBodyOutputStream = null;
            try {
                httpResponse = httpClient.execute(method);
                int status = httpResponse.getStatusLine().getStatusCode();
                if (status != HttpStatus.SC_OK) {
                    String errorMsg = CustomStringUtils.append("The remote service[", 
                            method.getURI(), "] respose an error status:", status);
                    logger.error(errorMsg);
                    if (status >= 500 && status < 600) {
                        throw new IOException(errorMsg);
                    }
                }
                
                // 获取响应头
                Map<String, String> responseHeaders = null;
                Header[] httpHeaders = httpResponse.getAllHeaders();
                if (httpHeaders != null && httpHeaders.length > 0) {
                    responseHeaders = new HashMap<String, String>(httpHeaders.length);
                    for (Header header : httpHeaders) {
                        responseHeaders.put(header.getName(), header.getValue());
                    }
                }
                
                // 获取响应体
                byte[] responseBody = null;
                HttpEntity httpEntity = httpResponse.getEntity();
                if (httpEntity != null) {
                    responseBodyInputStream = httpEntity.getContent();
                    if (responseBodyInputStream != null) {
                        responseBodyOutputStream = new ByteArrayOutputStream();
                        IOUtils.copy(responseBodyInputStream, responseBodyOutputStream);
                        responseBody = responseBodyOutputStream.toByteArray();
                    } else {
                        logger.warn(CustomStringUtils.append("The remote service[", 
                                method.getURI(), "] respose entity content is null. status:", status));
                    }
                } else {
                    logger.warn(CustomStringUtils.append("The remote service[", 
                            method.getURI(), "] respose entity is null. status:", status));
                }
                
                return new PCIHttpResponse(responseHeaders, responseBody);
            } catch (IOException e) {
                logger.error("Access to the remote service[" + method.getURI() + "] error.", e);
                throw e;
            } finally {
                IOUtils.closeQuietly(responseBodyInputStream);
                IOUtils.closeQuietly(responseBodyOutputStream);
    //            method.releaseConnection();
                IOUtils.closeQuietly(httpResponse);
                IOUtils.closeQuietly(httpClient);
            }
        }
    
    }

    单元测试示例(本示例为双向认证示例,单向认证则对应修改PCIHttpClientImpl4的构造参数即可):

        @Test
        public void testClock() throws Exception {
            String testUrl = "https://mail.xxxxxx.com:8440/service";
            Map<String, String> map = new HashMap<String, String>();
            
            map.put("messageType", "2058");
            map.put("accessUser", "gxecard_test_user_zhengchuan");
            map.put("terminalNo", "1");
            
            String parameter = JSON.toJSONString(map);
            String requestJson = "parameter=" + parameter;
            System.out.println("requestJson:" + requestJson);
            
    //        httpClient = new PCIHttpClientImpl4(true, false, 
    //                true, true, 
    //                "D:\keystore.jks", "123456", "123456");
                
        
                    //证书可以是jks格式也可以是p12格式 
            httpClient = new PCIHttpClientImpl4(true, false, 
            true, true, 
            "D:\keystore.p12", "123456", "123456");
            
            PCIHttpResponse httpResponse = null;
            httpResponse = httpClient.sendPost(testUrl, null, null, requestJson, "UTF-8", 55 * 1000);
            
            System.out.println(httpResponse.getBodyString());
        }    
  • 相关阅读:
    日志收集
    解决spawn-fcgi child exited with: 1
    confluence启动关闭
    Informatica 启动、停止工作流命令
    启动obiee
    oracle修改连接空闲自动断开
    ORA-00845: MEMORY_TARGET not supported on this system
    svn执行clean up命令时报错
    手游推广
    phonegap/cordova 升级版本
  • 原文地址:https://www.cnblogs.com/alsodzy/p/8393671.html
Copyright © 2011-2022 走看看