HttpsURLConnection unexpected end of file from server

最近在与服务端联调https的时候,服务端返回:unexpected end of file from server

 

1.最开始使用httpRequest方法,返回unexpected end of file from server;

2.将HttpURLConnection 替换为HttpsURLConnection ,方法名改为httpsRequest,此时,代码中没有HttpURLConnection的使用;服务端返回正常;

3.由于http访问的需要,增加httpsRequest方法(使用HttpURLConnection类),此时,在使用httpsRequest方法访问https链接时,服务端返回unexpected end of file from server;

4.注释掉httpsRequest方法,服务端返回正常;

 

与以上接近玄学的解释不同,经过验证,确认为tomcat的JDK版本(8_131)对HttpsURLConnection 的支持有问题,改为8_172后,不再出现此问题。

 

package com.landicorp.platform.utils;

import com.landicorp.platform.common.ParamName;
import com.lwd.clusters.util.Logger;
import com.lwd.clusters.util.LoggerImpl;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.*;
import java.security.cert.CertificateException;

@Component("comon.utils.httputils")
public class HttpUtils {
    private static Logger logger = new LoggerImpl();
    private static SSLContext sslContext;

    @Value("${server.config.ssl.keystore.password}")
    private String keyStorePw;
    @Value("${server.config.ssl.keystore.filepath}")
    private String keyStoreFilePath;
    @Value("${server.config.ssl.truststore.filepath}")
    private String trustStoreFilePth;
    @Value("${server.config.ssl.truststore.password}")
    private String trustStorePw;

//    public JSONObject httpRequest(String urlStr,JSONObject paramJsonObj){
//        DataOutputStream bOutputStream = null;
//        InputStream inputStream = null;
//        JSONObject responseJson;
//        String errorMsg;
//        HttpURLConnection urlConnection = null;
//        try {
//            logger.info("url = "+ urlStr);
//            logger.info("param = "+ paramJsonObj.toString());
//            URL url = new URL(urlStr);
//            urlConnection = (HttpURLConnection) url.openConnection();
//
//            urlConnection.setDoInput(true);
//            urlConnection.setDoOutput(true);
//            urlConnection.setConnectTimeout(10*1000);
//            //urlConnection.setReadTimeout(5*1000);
//            urlConnection.setRequestMethod("POST");
//            urlConnection.setRequestProperty("Connection", "close");
//            urlConnection.setRequestProperty("Charset", "UTF-8");
//            urlConnection.setRequestProperty("User-Agent", "directclient");
//            urlConnection.setRequestProperty("Content-Type","application/json");
//
//            bOutputStream = new DataOutputStream(urlConnection.getOutputStream());
//            String paramStr = paramJsonObj.toString();
//            bOutputStream.write(paramStr.getBytes("UTF-8"));
//            bOutputStream.flush();
//
//            logger.info("http response,ResponseMessage=" + urlConnection.getResponseCode() +                                "ResponseMessage=" + urlConnection.getResponseMessage());
//
//            inputStream = urlConnection.getInputStream();
//            StringBuffer responseSb = new StringBuffer();
//            // 读取服务器数据
//            if (inputStream != null) {
//                ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
//                int len = -1;
//                byte[] buf = new byte[1024];
//                while ((len = inputStream.read(buf)) != -1) {
//                    baOutputStream.write(buf, 0, len);
//                }
//                baOutputStream.flush();
//                responseSb.append(baOutputStream.toString());
//            }
//            logger.info("http response,type=" + paramJsonObj.getString(ParamName.TYPE)
//                    + " jsonParam=" + responseSb);
//            // 解析服务器返回数据
//            responseJson = JSONObject.fromObject(responseSb.toString());
//
//            return responseJson;
//        } catch (Exception e) {
//            logger.error(e,"Exception");
//            e.printStackTrace();
//            errorMsg = e.getMessage();
//        } finally {
//            if(urlConnection !=null){
//                urlConnection.disconnect();
//                urlConnection = null;
//            }
//            try {
//                if(bOutputStream != null){
//                    bOutputStream.flush();
//                    bOutputStream.close();
//                }
//                if(inputStream != null)
//                    inputStream.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        responseJson = new JSONObject();
//        try {
//            responseJson.put("error", errorMsg);
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }
//        return responseJson;
//    }

    public JSONObject httpsRequest(String urlStr, JSONObject paramJsonObj) throws Exception {
        trustAllHttpsCertificates();
        DataOutputStream bOutputStream = null;
        InputStream inputStream = null;
        JSONObject responseJson;
        String errorMsg;
        HttpsURLConnection urlConnection = null;
        try {
            logger.info("url = "+ urlStr);
            logger.info("param = "+ paramJsonObj.toString());
            URL url = new URL(urlStr);
            urlConnection = (HttpsURLConnection) url.openConnection();

//            // 设置信任证书
//            if(urlConnection instanceof HttpsURLConnection) {
//                ((HttpsURLConnection) urlConnection)
//                        .setSSLSocketFactory(getSSLContext().getSocketFactory());
//            }

            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setConnectTimeout(10*1000);
            //urlConnection.setReadTimeout(5*1000);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Connection", "close");
            urlConnection.setRequestProperty("Charset", "UTF-8");
            urlConnection.setRequestProperty("User-Agent", "directclient");
            urlConnection.setRequestProperty("Content-Type","application/json");

            bOutputStream = new DataOutputStream(urlConnection.getOutputStream());
            String paramStr = paramJsonObj.toString();
            bOutputStream.write(paramStr.getBytes("UTF-8"));
            bOutputStream.flush();

            logger.info("http response,ResponseMessage=" + urlConnection.getResponseCode() +                                "ResponseMessage=" + urlConnection.getResponseMessage());

            inputStream = urlConnection.getInputStream();
            StringBuffer responseSb = new StringBuffer();
            // 读取服务器数据
            if (inputStream != null) {
                ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
                int len = -1;
                byte[] buf = new byte[1024];
                while ((len = inputStream.read(buf)) != -1) {
                    baOutputStream.write(buf, 0, len);
                }
                baOutputStream.flush();
                responseSb.append(baOutputStream.toString());
            }
            logger.info("http response,type=" + paramJsonObj.getString(ParamName.TYPE)
                    + " jsonParam=" + responseSb);
            // 解析服务器返回数据
            responseJson = JSONObject.fromObject(responseSb.toString());

            return responseJson;
        } catch (Exception e) {
            logger.error(e,"Exception");
            e.printStackTrace();
            errorMsg = e.getMessage();
        } finally {
            if(urlConnection !=null){
                urlConnection.disconnect();
                urlConnection = null;
            }
            try {
                if(bOutputStream != null){
                    bOutputStream.flush();
                    bOutputStream.close();
                }
                if(inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        responseJson = new JSONObject();
        try {
            responseJson.put("error", errorMsg);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return responseJson;
    }


    public SSLContext getSSLContext(){
        if(sslContext==null){
            try {
                KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(getkeyStore(),keyStorePw.toCharArray());
                KeyManager[] keyManagers = kmf.getKeyManagers();

                TrustManagerFactory trustManagerFactory=TrustManagerFactory.getInstance("SunX509");
                trustManagerFactory.init(getTrustStore());
                TrustManager[]  trustManagers= trustManagerFactory.getTrustManagers();

                sslContext = SSLContext.getInstance("TLS");
                sslContext.init(keyManagers, trustManagers, new SecureRandom());
                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (UnrecoverableKeyException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
        }
        return sslContext;
    }


    public KeyStore getkeyStore(){
        KeyStore keySotre=null;
        try {
            keySotre = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(new File(keyStoreFilePath));
            keySotre.load(fis, keyStorePw.toCharArray());
            fis.close();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return keySotre;
    }
    public KeyStore getTrustStore() throws IOException{
        KeyStore trustKeyStore=null;
        FileInputStream fis=null;
        try {
            trustKeyStore=KeyStore.getInstance("JKS");
            fis = new FileInputStream(new File(trustStoreFilePth));
            trustKeyStore.load(fis, trustStorePw.toCharArray());
        } 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{
            fis.close();
        }
        return trustKeyStore;
    }

    /**
     * 从网络Url中下载文件
     * @param urlStr
     * @param savePath
     * @throws IOException
     */
    public void  downLoadFromUrl(String urlStr,String savePath) throws Exception{
        logger.info("start download :"+urlStr);
        URL url = new URL(urlStr);
        trustAllHttpsCertificates();
        HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
//        urlConnection.setDoInput(true);
//        urlConnection.setDoOutput(false);
//        urlConnection.setConnectTimeout(10*1000);
//        urlConnection.setReadTimeout(10*1000);
        urlConnection.setRequestMethod("GET");
//        urlConnection.setRequestProperty("Connection", "close");
        urlConnection.setRequestProperty("Charset", "UTF-8");
        urlConnection.setRequestProperty("Content-Type","application/octet-stream");
        //防止屏蔽程序抓取而返回403错误
        //urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        int code = urlConnection.getResponseCode();
        if (code != HttpURLConnection.HTTP_OK) {
            throw new Exception("文件读取失败:"+code);
        }
        //conn.setRequestProperty("lfwywxqyh_token",toekn);
//        // 设置信任证书
//        if(urlConnection instanceof HttpsURLConnection) {
//            ((HttpsURLConnection) urlConnection)
//                    .setSSLSocketFactory(getSSLContext().getSocketFactory());
//        }
        //得到输入流
        InputStream inputStream = urlConnection.getInputStream();
        File targetFile = new File(savePath);
        if(!targetFile.getParentFile().exists()){
            FileUtils.forceMkdir(targetFile.getParentFile());
        }
        //文件保存位置
        FileOutputStream fos = new FileOutputStream(targetFile,false);

        try {
            byte[] buffer = new byte[1024 * 512];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
        }catch (IOException e){
            e.printStackTrace();
            if(inputStream != null)
                inputStream.close();
            if(fos != null){
                fos.flush();
                fos.close();
            }
        }
    }


    public void trustAllHttpsCertificates() throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                //logger.info("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts,  new java.security.SecureRandom());
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值