一个奇怪的需求,前端拿到URL无法下载文件,需要请求后台下载。。。
不过也遇到了一些问题,刚开始文件无法下全,发现没有全部写入。
public void download(String path, HttpServletResponse response) throws IOException {
OutputStream toClient = null ;
InputStream fis = null;
try {
URL url = new URL(path);
String fileTyle=path.substring(path.lastIndexOf("/")+1,path.length());
// 以流的形式下载文件。
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
fis = connection.getInputStream();
byte[] buffer = readInputStream(fis);
fis.read(buffer);
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileTyle));
response.setContentType("application/octet-stream");
toClient = new BufferedOutputStream(response.getOutputStream());
toClient.write(buffer);
toClient.flush();
} catch (IOException ex) {
ex.printStackTrace();
}finally {
fis.close();
toClient.close();
}
}
public byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
上述方法本地测试没有问题,但是放到服务器上 就无法下载https的资源。
此时需要绕过认证
public static void downloadPicture(String path,HttpServletRequest request) throws IOException {
InputStream fis = null;
FileOutputStream out = null;
String split = null ;
//文件后缀
String fileTyle = null;
//重命名的文件名
String sourceName = null;
//文件地址
String filePath = null;
File targetFile = null;
byte[] buffer = null;
try {
HttpsURLConnection httpsURLConnection = getHttpsURLConnection(path);
fileTyle=path.substring(path.lastIndexOf("/")+1,path.length());
buffer = FileUtil.readInputStream(httpsURLConnection.getInputStream());
split = fileTyle.substring(fileTyle.lastIndexOf(".") + 1);
sourceName = System.currentTimeMillis() + "." + split;
//此处为项目根目录下
filePath = request.getSession().getServletContext().getRealPath("/") + "upload" + File.separator ;
targetFile = new File(filePath);
//没有文件夹及创建文件夹
if (!targetFile.exists()) {
targetFile.mkdirs();
}
out = new FileOutputStream(filePath + sourceName);
out.write(buffer);
out.flush();
} catch (IOException ex) {
ex.printStackTrace();
}finally {
out.close();
}
}
getHttpsURLConnection方法
//method 请求方式 get post 一般为get 等
private static HttpsURLConnection getHttpsURLConnection(String uri,String method) throws IOException {
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
SSLSocketFactory ssf = ctx.getSocketFactory();
URL url = new URL(uri);
HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();
//绕过HTTPS相关证书关键代码-开始
httpsConn.setSSLSocketFactory(ssf);
//绕过HTTPS相关证书关键代码-结束
httpsConn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
httpsConn.setRequestMethod(method);
httpsConn.setDoInput(true);
httpsConn.setDoOutput(true);
return httpsConn;
}
private static final class DefaultTrustManager 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 null;
}
}