坑坑坑

作者: belllee | 来源:发表于2018-08-10 14:41 被阅读0次

    在使用Https下载图片,出现如下问题。最后发现是jdk 1.8.60问题,换成最新的1.8.172
    javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

    public class HttpService {
    private static final String CHINESE_REGX = "[\u4e00-\u9fa5]";
    private static final String PICTURE_REGX = "(/|=)[^/=?&]+\.(jpeg|gif|jpg|png|bmp|svg)";
    private static final Logger log = LoggerFactory.getLogger(HttpService.class);
    private final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
    return true;
    }
    };
    private static class TrustAnyTrustManager implements X509TrustManager
    {

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[]{};
        }
    }
    
    public static String encodeChinese(String url) {
        if (!StringUtils.isBlank(url)) {
            try {
                Matcher matcher = Pattern.compile(CHINESE_REGX).matcher(url);
                while (matcher.find()) {
                    String tmp = matcher.group();
                    url = url.replaceAll(tmp, java.net.URLEncoder.encode(tmp, "utf-8"));
                }
            } catch (UnsupportedEncodingException e) {
                log.error("encode url fail,url=" + url, e);
            }
        }
        return url;
    }
    
    public static String getFileNameFromUrl(String url) {
        Pattern pat = Pattern.compile(PICTURE_REGX);//正则判断
        Matcher mc = pat.matcher(url);//条件匹配
        while (mc.find()) {
            String substring = mc.group();//截取文件名后缀名
            return substring.substring(1);
        }
        return "dev.png";
    }
    
    public static String getFileExt(String file) {
        int i = file.lastIndexOf(".");
        return file.substring(i+1);
    }
    private static String getHeader() {
        String auth = "user:passwd";
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes());
        String authHeader = "Basic " + new String(encodedAuth);
        return authHeader;
    }
    
    /**
     * 增加相关header模拟网页访问,用以避免目标网站屏蔽爬虫
     * @param con
     */
    private static void addHeaderForCrawler(URLConnection con){
        con.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36");
    

    // con.setRequestProperty("Referer", "http://my.coms");
    con.setRequestProperty("Accept", "image/webp,image/apng,image/,/*;q=0.8");
    // con.setRequestProperty("Accept", "Encoding:gzip, deflate");
    con.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
    con.setRequestProperty("Cache-Control", "no-cache");
    }

    private static InputStream getIS(String picUrl, int apiTimeout){
        try {
            // 构造URL
            URL url = new URL(encodeChinese(picUrl));
            // 打开连接
            URLConnection piccon;
            //通过请求地址判断请求类型(http或者是https)
            if (url.getProtocol().toLowerCase().equals("https")) {
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
                https.setSSLSocketFactory(sc.getSocketFactory());
                https.setHostnameVerifier(DO_NOT_VERIFY);
                piccon = https;
            } else {
                piccon = (HttpURLConnection) url.openConnection();
            }
            addHeaderForCrawler(piccon);
            //设置请求超时为120s
            piccon.setConnectTimeout(apiTimeout * 1000);
    

    // if (picUrl.indexOf("myhost") > 0) {
    // piccon.setRequestProperty("Authorization", getHeader());
    // }
    // piccon.connect();
    // 输入流
    return piccon.getInputStream();
    } catch(Exception e){
    log.error("getInputStream fail",e);
    log.error("url="+picUrl);
    }
    return null;
    }

    /**
     * 从指定url地址下载文件,然后上传到文档服务器,返回文档的新url地址
     *
     * @param apiUrl 文档服务器地址
     * @param picUrl 文件url地址
     * @return String 文件在服务器保存绝对路径
     * @throws IOException
     */
    public static String saveUrlToFdfs(String apiUrl, int apiTimeout, String picUrl) throws IOException {
        String result = "";
        String fileName = getFileNameFromUrl(picUrl);
        InputStream in = getIS(picUrl, apiTimeout);
    
        if (in == null) {
            log.error("url is illegal,url="+picUrl);
            return "";
        }
        BufferedImage img;
        try {
            img = ImageIO.read(in);
            if(img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0){
                in.close();
                log.error("url is not image,url="+picUrl);
                return "";
            }
        } catch (Exception e) {
            log.error("read url to image fail,url="+picUrl);
            log.error("exception",e);
            return "";
        } finally {
           in.close();
        }
        URL urlObj = new URL(apiUrl);
        // 连接
        HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
        con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setUseCaches(false); // post方式不能使用缓存
    
        // 设置请求头信息
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");
        // 设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
    
        // 请求正文信息
        // 第一部分:
        StringBuilder sb = new StringBuilder();
        sb.append("--"); // 必须多两道线
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"file1\";filename=\"" + fileName + "\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n");
        byte[] head = sb.toString().getBytes("utf-8");
    
        // 获得输出流
        OutputStream out = new DataOutputStream(con.getOutputStream());
        // 输出表头
        out.write(head);
    
        // 文件正文部分
        // 输入流
        in = getIS(picUrl, apiTimeout);
        if (in == null) {
            log.error("url is illegal,url="+picUrl);
            return "";
        }
    

    // in.close();
    try {
    int bytes = 0;
    int fileSize = 0;
    byte[] bufferOut = new byte[1024];
    while ((bytes = in.read(bufferOut)) != -1) {
    fileSize += bytes;
    out.write(bufferOut, 0, bytes);
    }
    if(fileSize < 100){
    log.error("fileSize to small,size="+fileSize);
    log.error("picUrl="+picUrl);
    return "";
    }
    } finally {
    in.close();
    }
    // 结尾部分
    byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
    out.write(foot);
    out.flush();
    out.close();

        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = null;
        try {
            // 定义BufferedReader输入流来读取URL的响应
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            result = buffer.toString();
        } catch (IOException e) {
            log.error("发送POST请求出现异常,picUrl=" + picUrl, e);
            throw new IOException("数据读取异常");
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        if (StringUtils.isBlank(result)) {
            log.error("返回值为空,picUrl=" + picUrl);
            return "";
        }
        return getPictureUrl(result);
    }
    
    
    public static String getPictureUrl(String jsonStr) {
        if (!StringUtils.isBlank(jsonStr)) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                jsonStr = jsonStr.replace("“", "\"");
                jsonStr = jsonStr.replace("”", "\"");
                log.info("jsonStr=" + jsonStr);
                FdfsFile[] datas = mapper.readValue(jsonStr, FdfsFile[].class);
                log.info("array length=" + datas.length);
                if (datas.length == 1 && !StringUtils.isBlank(datas[0].groupName) && !StringUtils.isBlank(datas[0].remoteFileName)) {
                    return "/" + datas[0].groupName + "/" + datas[0].remoteFileName;
                }
            } catch (Exception e) {
                log.error("Passe json string fail,str=" + jsonStr, e);
            }
        }
        return "";
    }
    
    /**
     * 从指定url地址下载文件
     *
     * @param response http响应
     * @param picUrl   文件url地址
     * @param fileName   文件名
     * @return void
     * @throws IOException
     */
    public static void downloadFileByUrl(HttpServletResponse response, String picUrl, String fileName) {
        InputStream in = null;
        OutputStream out = null;
        try {
            // 输入流
            in = getIS(picUrl, 120);
            if (in == null) {
                log.error("url is illegal,url="+picUrl);
                return;
            }
            //写图片
            response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
            out = new BufferedOutputStream(response.getOutputStream());
            //读取图片
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            out.flush();
        } catch(Exception e){
            log.error("doawnload file fail=",e);
            log.error("file url="+picUrl);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch(Exception ex){
                log.error("close stream fail=",ex);
            }
        }
    }
    /**
     * 从指定url读取图片
     *
     * @param response http响应
     * @param picUrl   图片url地址
     * @return void
     * @throws IOException
     */
    public static void showPicByUrl(HttpServletResponse response, String picUrl) {
        InputStream in = null;
        OutputStream out = null;
        try {
            // 输入流
            in = getIS(picUrl, 120);
            if (in == null) {
                log.error("url is illegal,url="+picUrl);
                return;
            }
    
            //写图片
            response.setContentType("image/jpeg");
            response.setCharacterEncoding("UTF-8");
            out = new BufferedOutputStream(response.getOutputStream());
            //读取图片
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            out.flush();
        } catch(Exception e){
            log.error("show pic fail=",e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch(Exception ex){
                log.error("close stream fail=",ex);
            }
        }
    }
    

    }

    相关文章

      网友评论

          本文标题:坑坑坑

          本文链接:https://www.haomeiwen.com/subject/emgkbftx.html