坑坑坑

在使用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);
        }
    }
}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容