• 使用URLConnection进行访问


    用URLConnection写的一个http和https请求的工具类。

    支持双向验证。如果对方要验证我们发送的证书,发送前先setKeyStore();如果我们要验证对方发送的证书,发送前先setTrustStore()。

    package test;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    import java.net.MalformedURLException;
    import java.net.ProtocolException;
    import java.net.Proxy;
    import java.net.Socket;
    import java.net.URL;
    import java.net.URLConnection;
    import java.net.URLEncoder;
    import java.security.KeyManagementException;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.Principal;
    import java.security.PrivateKey;
    import java.security.SecureRandom;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.HashMap;
    import java.util.Map;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.KeyManager;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509KeyManager;
    import javax.net.ssl.X509TrustManager;
    import org.apache.log4j.Logger;
    import sun.misc.BASE64Encoder;
    
    public class HttpUtil {
        private static Logger logger = Logger.getLogger(HttpUtil.class);
        //默认https协议 TLSv1
        private String DEFAULT_HTTPS_PROTOCOLS = "TLSv1";
        //默认请求方式 POST
        private String DEFAULT_REQUEST_METHOD = "POST";
        //默认接收所有格式
        private String DEFAULT_ACCEPT = "*/*";
        //默认字编码 UTF-8
        private String DEFAULT_CHARSET = "UTF-8";
        //默认发送数据格式
        private String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
        //默认请求后保持连接
        private String DEFAULT_CONNECTION = "Keep-Alive";
        //默认模拟浏览器发送
        private String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1";
        //默认连接超时时间 6s
        private int DEFAULT_CONNECT_TIMEOUT = 6 * 1000;
        //默认读取超时时间 6s
        private int DEFAULT_READ_TIMEOUT = 6 * 1000;
        //接收到回复的成功码 200
        private final static int RESPONSE_CODE_SUCCESS = 200;
        //传入补充的消息头信息
        private Map<String, String> HEADER_IN = null;
        //发送证书给对方,默认不发送
        private boolean CERT_SEND = false;
        //验证对方发来的证书,默认不验证
        private boolean CERT_AUTH = false;
        //密钥库路径
        private String KEYSTORE_PATH = "";
        //密钥库密码
        private String KEYSTORE_PASSWORD = "";
        //信任证书库路径
        private String TRUSTSTORE_PATH = "";
        //信任证书库密码
        private String TRUSTSTORE_PASSWORD = "";
        
        /**
         * 设置https协议 ,默认TLSv1
         * @param protocols
         */
        public void setHttpsProtocols(String protocols){
            this.DEFAULT_HTTPS_PROTOCOLS = protocols;
        }
        
        /**
         * 设置字符编码,默认UTF-8
         * @param charSet
         */
        public void setCharSet(String charSet){
            this.DEFAULT_CHARSET = charSet;
        }
        
        /**
         * 设置数据格式,默认application/x-www-form-urlencoded
         * @param contentType
         */
        public void setContentType(String contentType){
            this.DEFAULT_CONTENT_TYPE = contentType;
        }
        
        /**
         * 设置连接超时时间 默认 6s
         * @param connectTimeout
         */
        public void setConnectTimeout(int connectTimeout){
            this.DEFAULT_CONNECT_TIMEOUT = connectTimeout;
        }
        
        /**
         * 设置读取超时时间 默认 6s
         * @param connectTimeout
         */
        public void setReadTimeout(int readTimeout){
            this.DEFAULT_READ_TIMEOUT = readTimeout;
        }
        
        /**
         * 传入补充消息头header信息
         * @param headerIn
         */
        public void setHeaderIn(Map<String, String> headerIn) {
            this.HEADER_IN = headerIn;
        }
        
        /**
         * 如果对方需要验证本方证书,setKeyStore。[本方的证书应提前发送给对方,存入对方证书库。]
         * KeyStore[存放本方密钥对的文件]。交互时,它会将本方证书自动发送过去,与对方信任证书库中的证书进行匹配。
         * @param keyStorePath
         * @param keyStorePassword
         */
        public void setKeyStore(String keyStorePath, String keyStorePassword){
            this.KEYSTORE_PATH = keyStorePath;
            this.KEYSTORE_PASSWORD = keyStorePassword;
            this.CERT_SEND = true;//从密钥库拿出证书发送给对方。
        }
        
        /**
         * 如果本方需要验证对方证书,setTrustStore。[拿到对方证书,提前存入我们的信任证书库]
         * TrustStore[存放并信任对方证书的文件]。交互时,收到对方的证书会与trustStore中的证书进行匹配。
         * @param keyStorePath
         * @param keyStorePassword
         */
        public void setTrustStore(String trustStorePath, String trustStorePassword){
            this.TRUSTSTORE_PATH = trustStorePath;
            this.TRUSTSTORE_PASSWORD = trustStorePassword;
            this.CERT_AUTH = true;//信任库验证对方发来的证书。
        }
    
        /**
         * 发送请求
         * @param url url地址
         * @param paramMap 请求参数Map
         * @return
         */
        public String post(String url, Map<String, String> paramMap){
            //默认不使用网络代理
            return post(url, paramMap, null);
        }
        
        /**
         * 发送请求
         * @param url url地址
         * @param param 请求参数Str
         * @return
         */
        public String post(String url, String param){
            //默认不使用网络代理
            return post(url, param, null);
        }
        
        /**
         * 发送请求
         * @param url url地址
         * @param paramMap 请求参数Map
         * @param proxyMap 如果需要添加网络代理,使用本类的addProxy()方法获取并添加。
         * @return
         */
        public String post(String url, Map<String, String> paramMap, Map<String, Object> proxyMap){
            
            String param = paramMapToStr(paramMap);
            
            return post(url, param, proxyMap);
        }
        
        /**
         * 发送请求
         * @param url url地址
         * @param param 请求参数串
         * @param proxyMap 如果需要添加网络代理,使用addProxy()方法获取。
         * @return
         */
        public String post(String url, String param, Map<String, Object> proxyMap){
            url = formatUrl(url);
            logger.info("url address: "+url);
            
            if(url==null||url.trim().length()==0){
                logger.error("get url error...");
                return "";
            }
            if(param==null||param.trim().length()==0){
                param = "";
            }
            
            URLConnection urlConnection = getUrlConnection(url, proxyMap);
            if(urlConnection==null){
                logger.error("create connection error...");
                return "";
            }
            
            HttpURLConnection httpURLConnection = null;
            if(url.startsWith("https")){
                logger.info("connection with https, set SSLContext...");
                SSLSocketFactory sslSocketFactory = null;
                try {
                    
                    //System.setProperty("https.protocols", DEFAULT_HTTPS_PROTOCOLS);
    
                    String sslContextType = "TLS";
                    if(DEFAULT_HTTPS_PROTOCOLS.toUpperCase().contains("TLS")){
                        sslContextType = "TLS";
                    } else if (DEFAULT_HTTPS_PROTOCOLS.toUpperCase().contains("SSL")){
                        sslContextType = "SSL";
                    }
                    
                    SSLContext sslContext = SSLContext.getInstance(sslContextType);
                    KeyManager[] keyManagers = initKeyManager();
                    TrustManager[] trustManagers = initTrustManager();
                    sslContext.init(keyManagers, trustManagers, new SecureRandom());
                    sslSocketFactory = sslContext.getSocketFactory();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                }
                
                HttpsURLConnection httpsURLConnection = (HttpsURLConnection)urlConnection;
                httpsURLConnection.setSSLSocketFactory(sslSocketFactory);
                httpsURLConnection.setHostnameVerifier(initHostnameVerifier());
                
                httpURLConnection = httpsURLConnection;
            }else{
                httpURLConnection = (HttpURLConnection)urlConnection;
            }
            
            //如果有代理,查看是否有账号密码授权,进行授权
            Map<String, String> proxyAccountInfo = getRequestPropertyInfoForProxy(proxyMap);
            if(proxyAccountInfo!=null&&proxyAccountInfo.size()>0){
                String propertyKey = proxyAccountInfo.get("key");
                String propertyValue = proxyAccountInfo.get("value");
                httpURLConnection.setRequestProperty(propertyKey, propertyValue);
            }
            //默认POST
            try {
                httpURLConnection.setRequestMethod(DEFAULT_REQUEST_METHOD);
            } catch (ProtocolException e) {
                e.printStackTrace();
            }
            httpURLConnection.setDoInput(true);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setConnectTimeout(DEFAULT_READ_TIMEOUT);
            httpURLConnection.setReadTimeout(DEFAULT_CONNECT_TIMEOUT);
            httpURLConnection.setRequestProperty("accept", DEFAULT_ACCEPT);
            httpURLConnection.setRequestProperty("connection", DEFAULT_CONNECTION);
            httpURLConnection.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
            httpURLConnection.setRequestProperty("Charset", DEFAULT_CHARSET);
            httpURLConnection.setRequestProperty("Content-type", DEFAULT_CONTENT_TYPE + ";charset=" + DEFAULT_CHARSET);
            httpURLConnection.setRequestProperty("Content-Length", String.valueOf(param.length()));
            
            //补充header信息
            addHeaderIn(httpURLConnection, HEADER_IN);
            
            BufferedWriter bw = null;
            OutputStreamWriter osw = null;
            OutputStream os = null;
            try {
                //post getOutputStream(),会自动调用connect()方法,所以不用再调用connect()
                os = httpURLConnection.getOutputStream();
                logger.info("connection connected...");
                
                osw = new OutputStreamWriter(os, DEFAULT_CHARSET);
                bw = new BufferedWriter(osw);
                bw.write(param);
                bw.flush();
                
                logger.info("has been sent...");
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    if(bw!=null){
                        bw.close();
                    }
                    if(osw!=null){
                        osw.close();
                    }
                    if(os!=null){
                        os.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            String result = "";
            BufferedReader br = null;
            InputStreamReader isr = null;
            InputStream is = null;
            try {
                int responseCode = httpURLConnection.getResponseCode();
                logger.info("response code: "+responseCode);
                if(responseCode == RESPONSE_CODE_SUCCESS){
                    is = httpURLConnection.getInputStream();
                    isr = new InputStreamReader(is, DEFAULT_CHARSET);
                    br = new BufferedReader(isr);
                    
                    StringBuilder sb = new StringBuilder();
                    String temp = null;
                    while((temp=br.readLine())!=null){
                        sb.append(temp);
                    }
                    
                    result = sb.toString();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if(br!=null){
                        br.close();
                    }
                    if(isr!=null){
                        isr.close();
                    }
                    if(is!=null){
                        is.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            httpURLConnection.disconnect();
            logger.info("connection close...");
            
            logger.info("result: " + result);
            return result;
        }
        
        /**
         * 传入补充消息头header信息
         * @param headerIn
         */
        private void addHeaderIn(HttpURLConnection httpURLConnection, Map<String, String> headerIn){
            //传入补充消息头header信息
            if(headerIn!=null&&headerIn.size()>0){
                for(Map.Entry<String, String> entry : headerIn.entrySet()){
                    String key = entry.getKey();
                    String value = entry.getValue();
                    
                    httpURLConnection.addRequestProperty(key, value);
                }
            }
        }
        
        /**
         * 获取URLConnection
         * @param url
         * @param proxyMap
         * @return
         */
        private URLConnection getUrlConnection(String url, Map<String, Object> proxyMap){
            URLConnection urlConnection = null;
            try {
                URL urlObject = new URL(url);
    
                if(proxyMap!=null&&proxyMap.size()>0&&proxyMap.get("proxy")!=null){
                    Proxy proxy = (Proxy)proxyMap.get("proxy");
                    urlConnection = urlObject.openConnection(proxy);
                    logger.info("use proxy...");
                }else{
                    urlConnection = urlObject.openConnection();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return urlConnection;
        }
        
        /**
         * 添加代理
         * @param hostname
         * @param port
         * @param account
         * @param password
         * @return
         */
        public Map<String, Object> addProxy(String hostname,int port,String account,String password){
            Proxy proxy = null;
            try {
                InetSocketAddress address = new InetSocketAddress(hostname, port);
                proxy = new Proxy(Proxy.Type.HTTP, address);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("create proxy error...");
            }
            
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("proxy", proxy);
            map.put("account", account);
            map.put("password", password);
            return map;
        }
        
        /**
         * 如果有代理,查看是否有账号密码授权,进行授权,获取代理账户密码信息,并进行处理
         * @param proxyMap
         * @return
         */
        private Map<String, String> getRequestPropertyInfoForProxy(Map<String, Object> proxyMap){
            Map<String, String> map = new HashMap<String, String>();
            if(proxyMap==null||proxyMap.size()==0){
                return map;
            }
            Object proxyObj = proxyMap.get("proxy");
            if(proxyObj==null){
                return map;
            }
            
            Object accountObj = proxyMap.get("account");
            Object passwordObj = proxyMap.get("password");
            
            String account = "";
            if(accountObj!=null){
                account = (String)accountObj;
            }
            String password = "";
            if(passwordObj!=null){
                password = (String)passwordObj;
            }
            
            //如果有代理,查看是否有账号密码授权,进行授权
            if(!"".equals(account)&&!"".equals(password)){
                logger.info("proxy account: " + account + " / proxy pass: " + password);
                String headerKey = "Proxy-Authorization";
                
                String headerVal = "";
                byte[] valByte = null;
                try {
                    valByte = (account+": "+password).getBytes(DEFAULT_CHARSET);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                if(valByte!=null&&valByte.length>0){
                    BASE64Encoder base64Encoder = new BASE64Encoder();
                    headerVal = "Basic " + base64Encoder.encode(valByte);
                }
                
                map.put("key", headerKey);
                map.put("value", headerVal);
            }
            
            return map;
        }
        
        /**
         * 格式化url,获取?前边的url请求地址
         * @param url
         * @return
         */
        private static String formatUrl(String url){
            if(url==null||url.trim().length()==0){
                logger.error("url empty...");
                return "";
            }
            
            if(!url.startsWith("http")){
                if(url.startsWith("//")){
                    url = "http:" + url;
                }else{
                    url = "http://" + url;
                }
            }
            return url;
        }
        
        /**
         * map类型的参数换成str参数。
         * @param paramMap
         * @return
         */
        private String paramMapToStr(Map<String, String> paramMap){
            if(paramMap==null||paramMap.size()==0){
                return "";
            }
            StringBuffer param = new StringBuffer();
            
            try {
                for(Map.Entry<String, String> entry :paramMap.entrySet()){
                    String key = entry.getKey();
                    String value = entry.getValue();
                    value = (value==null?"":value);
                    param.append(key);
                    param.append("=");
                    param.append(URLEncoder.encode(value, DEFAULT_CHARSET));
                    param.append("&");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return param.toString();
        }
        
        /**
         * 初始化keyStore
         * @return
         */
        private KeyManager[] initKeyManager(){
            //从密钥库拿出证书发送给对方。
            if(CERT_SEND){
                File keyStoreFile = new File(KEYSTORE_PATH);
                if(!(keyStoreFile.exists()&&keyStoreFile.isFile())){
                    logger.error("init keyStoreFile error...");
                    KeyManager[] keyManagers = {};
                    return keyManagers;//因为返回null,可以正常访问,所以采用这种写法,可以拦截住。
                }
                
                InputStream keyStoreInput = null;
                try {
                    keyStoreInput = new FileInputStream(keyStoreFile);
                    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                    keyStore.load(keyStoreInput, KEYSTORE_PASSWORD.toCharArray());
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                    keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
                    KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
                    return keyManagers;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (UnrecoverableKeyException e) {
                    e.printStackTrace();
                } finally {
                    if(keyStoreInput!=null){
                        try {
                            keyStoreInput.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }
            
            KeyManager keyManager = new X509KeyManager() {
                
                @Override
                public String[] getServerAliases(String arg0, Principal[] arg1) {
                    return null;
                }
                
                @Override
                public PrivateKey getPrivateKey(String arg0) {
                    return null;
                }
                
                @Override
                public String[] getClientAliases(String arg0, Principal[] arg1) {
                    return null;
                }
                
                @Override
                public X509Certificate[] getCertificateChain(String arg0) {
                    return null;
                }
                
                @Override
                public String chooseServerAlias(String arg0, Principal[] arg1, Socket arg2) {
                    return null;
                }
                
                @Override
                public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) {
                    return null;
                }
            };
            
            KeyManager[] keyManagers = {keyManager};
            return keyManagers;
        }
        
        /**
         * 初始化trustStore
         * @return
         */
        private TrustManager[] initTrustManager(){
            //信任库验证对方发来的证书。
            if(CERT_AUTH){
                File trustStoreFile = new File(TRUSTSTORE_PATH);
                if(!(trustStoreFile.exists()&&trustStoreFile.isFile())){
                    logger.error("init trustStoreFile error...");
                    TrustManager[] trustManagers = {};
                    return trustManagers;//因为返回null,可以正常访问,所以采用这种写法,可以拦截住。
                }
                
                InputStream trustStoreInput = null;
                try {
                    trustStoreInput = new FileInputStream(trustStoreFile);
                    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                    trustStore.load(trustStoreInput, TRUSTSTORE_PASSWORD.toCharArray());
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    trustManagerFactory.init(trustStore);
                    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
                    return trustManagers;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(trustStoreInput!=null){
                        try {
                            trustStoreInput.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }
            
            TrustManager trustManager = new X509TrustManager() {
                
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                
                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    
                }
                
                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    
                }
            };
            
            TrustManager[] TrustManagers = {trustManager};
            return TrustManagers;
        }
        
        /**
         * 域名验证,默认true验证通过
         * @return
         */
        private HostnameVerifier initHostnameVerifier(){
            return new HostnameVerifier() {
                
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
        }
        
    }
  • 相关阅读:
    C#循环页面form中控件
    鼠标放到按钮上页面样式发生变化
    access INSERT INTO 语句的语法错误
    更改水晶报表数据源
    C# byte[]与string互转
    禁用右键
    showModalDialog IE9 报错
    ListBox 循环删除当前项
    showModalDialog 刷新本页面,不重新发送信息,则无法刷新网页,Page_PreRender
    敏捷模式开发(转)
  • 原文地址:https://www.cnblogs.com/jinzhiming/p/8533869.html
Copyright © 2020-2023  润新知