坑坑坑

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

}

你可能感兴趣的:(坑坑坑)