网络资源url转化为file对象下载文件;https地址url.openStream()时ssl证书忽略
注:只测试过网络图片资源。
一、使用org.apache.commons.io.FileUtils
二、
三、httpURLConnection.disconnect();
四、
import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.UUID; /** * URLConnection的连接、超时、关闭用法总结 : https://www.cnblogs.com/achengmu/p/10057243.html * RandomAccessFile简介与使用 : https://blog.csdn.net/qq_31615049/article/details/88562892 */ public class Test { private static String dirPath = "F:\\\\upload2222"; public static void main(String[] args) throws IOException { String url = "http://imgsrc.baidu.com/forum/pic/item/a701a18b87d6277fff058e4125381f30e924fcb0.jpg"; //方式1 // copyByUrl(url, rewriteFileName(url), dirPath); //方式2 // urlOpenStreamWrite(url, "antStorm_100171553219414047v.jpg", dirPath); //方式3 // downLoadByUrl(url, "antStorm_100171553219414047m3v.jpg", dirPath); //方式4 randomAccessWrite(url); } /** * import org.apache.commons.io.FileUtils; */ public static void copyByUrl(String urlStr,String fileName,String savePath)throws IOException { URL url = new URL(urlStr); FileUtils.copyURLToFile(url, new File(savePath+ File.separator+fileName)); } /** * urlOpenStreamWrite file */ public static void urlOpenStreamWrite(String urlStr,String fileName,String savePath) throws IOException { URL url =new URL(urlStr); InputStream is = url.openStream(); // int available = is.available(); // System.out.println(available); File file = new File(savePath + File.separatorChar + fileName); //不存在,创建必要的(多层)目录 File parentDir = file.getParentFile(); if(!parentDir.exists()) parentDir.mkdirs(); FileOutputStream fos = new FileOutputStream(file); byte[] buffer = new byte[2048]; int len; while ((len = is.read(buffer)) != -1) { fos.write(buffer, 0, len); } if(fos!=null) fos.close(); if(is!=null) is.close(); } /** * (HttpURLConnection)url.openConnection() * httpURLConnection.getInputStream() */ public static void downLoadByUrl(String urlStr,String fileName,String savePath)throws IOException{ URL url =new URL(urlStr); /** * 此处的urlConnection对象实际上是根据URL的 * 请求协议(此处是http)生成的URLConnection类 * 的子类HttpURLConnection,故此处最好将其转化 * 为HttpURLConnection类型的对象,以便用到 * HttpURLConnection更多的API. */ HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置超时间为3秒 // conn.setConnectTimeout(5*1000); //防止屏蔽程序抓取而返回403错误 // conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); //得到输入流 InputStream is = conn.getInputStream(); //偷看有效长度 // int available = is.available(); //文件保存位置 File saveDir =new File(savePath); if(!saveDir.exists()) saveDir.mkdirs(); File file =new File(saveDir + File.separator + fileName); FileOutputStream fos =new FileOutputStream(file); //获取缓存内容的byte数组,可以转化成其他流 byte[] cachedBytes =readInputStream(is); fos.write(cachedBytes); if(fos!=null) fos.close(); if(is!=null) is.close(); System.out.println("info:"+url+" download success");
//断开
conn.disconnect(); //删除文件 // file.delete(); } /** * 获取缓存内容的byte数组,可以转化成其他流 */ public static 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(); } /** * rewriteFileName重命名,UUIU */ public static String rewriteFileName(String oleFileName) { oleFileName = getOriginalFileName(oleFileName); if (StringUtils.isEmpty(oleFileName)) { return oleFileName; } //得到后缀 if (oleFileName.indexOf(".") == -1) { //对于没有后缀的文件,直接返回重命名 return UUID.randomUUID().toString(); } String[] arr = oleFileName.split("\\."); // 根据uuid重命名图片 String fileName = UUID.randomUUID().toString() + "." + arr[arr.length - 1]; return fileName; } /** * 把带路径的文件地址解析为真实文件名 /25h/upload/hc/1448089199416_06cc07bf-7606-4a81-9844-87d847f8740f.mp4 解析为 1448089199416_06cc07bf-7606-4a81-9844-87d847f8740f.mp4 * @param url */ public static String getOriginalFileName(final String url) { if (StringUtils.isEmpty(url)) { return url; } String newUrl = url; newUrl = newUrl.split("[?]")[0]; String[] bb = newUrl.split("/"); String fileName = bb[bb.length - 1]; return fileName; } /** * RandomAccessFile 读写文件 * https://blog.csdn.net/qq_31615049/article/details/88562892 */ private static void writeFile(InputStream is, File storeFile){ RandomAccessFile raf = null; int buffer_len = 1024; byte[] buffer = new byte[buffer_len]; int readLen = 0; try{ raf = new RandomAccessFile(storeFile, "rw"); raf.seek(raf.length());//设置光标位置。从此处开始写(插)入文件内容。 while(-1 != (readLen = is.read(buffer, 0, buffer_len))){ raf.write(buffer, 0, readLen); } } catch (Exception e){ e.printStackTrace(); } finally { try { if(raf != null) raf.close(); if(is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * * @param funnyUrl * @throws IOException */ public static void randomAccessWrite(String funnyUrl) throws IOException { // String newFIleName = rewriteFileName(funnyUrl).replace("-", ""); //创建tempfile取用后缀就够了 String newFIleName = getOriginalFileName(funnyUrl); String suffix = newFIleName.substring(newFIleName.lastIndexOf(".")); //指定路径,否则存储在默认路径中 File tempFile = File.createTempFile("url_dwn", suffix, new File(dirPath)); //File tempFile = File.createTempFile("url_dwn", suffix); URL url = new URL(funnyUrl); InputStream is = url.openStream(); writeFile(is, tempFile); } }
java通过url得到文件对象(支持http和https):
https://blog.csdn.net/qq_21235239/article/details/99415421
五、trash
/** * 后台验证:以后缀名称检查图片格式 * @param files * @return 不容许的文件名称,以“ , ”隔开 */ public static String checkFileType(MultipartFile[] files) { StringBuilder rejectFileNames = new StringBuilder(); for (MultipartFile file : files) { String originalFilename = file.getOriginalFilename(); String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); //枚举中可以上传的文件类型 List<String> fileTypes = FileType.getFileTypes(); //可以上传的文件类型检查 if(!fileTypes.contains(suffix)) { rejectFileNames.append(originalFilename).append(" , "); } } if(rejectFileNames.length() > 0) { int idx = rejectFileNames.lastIndexOf(","); //删除末尾的自定义分隔符 rejectFileNames.delete(idx - 1, rejectFileNames.length()); } return rejectFileNames.toString(); } /** * 图片格式后缀名称枚举 */ enum FileType { PEG("peg"), JPG("jpg"), BMP("bmp"), PNG("png"); private String type; FileType(String type) { this.type = type; } public String getType() { return type; } public static List<String> getFileTypes() { FileType[] fileTypes = FileType.values(); List<String> types = Arrays.stream(fileTypes).map(FileType::getType).collect(Collectors.toList()); return types; } }
http请求下载服务器文件
1.配置匿名访问下载
@Bean public ShiroFilterFactoryBean shiroFilter( @Autowired(required = false) @Qualifier("shiroFilters") Map<String, Filter> shiroFilters, @Autowired(required = false) @Qualifier("shiroFilterChainDefinitionMap") Map<String, String> shiroFilterChainDefinitionMap) { if (shiroFilters == null) { shiroFilters = new LinkedHashMap<String, Filter>(); shiroFilters.put("token", new ShiroTokenFilter()); } if (shiroFilterChainDefinitionMap == null) { shiroFilterChainDefinitionMap = new LinkedHashMap<String, String>(); shiroFilterChainDefinitionMap.put("/isAuthen", "anon"); shiroFilterChainDefinitionMap.put("/login", "anon"); shiroFilterChainDefinitionMap.put("/logout", "anon"); shiroFilterChainDefinitionMap.put("/**", "token"); shiroFilterChainDefinitionMap.put("/currentAPK", "anon"); } ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager()); shiroFilter.setFilters(shiroFilters); shiroFilter.setFilterChainDefinitionMap(shiroFilterChainDefinitionMap); return shiroFilter; } /** * 权限认证管理器 * @return 认证管理器 */ @Bean public org.apache.shiro.mgt.SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setCacheManager(cacheManager()); securityManager.setSessionManager(sessionManager()); securityManager.setRealm(realm()); return securityManager; }
2.下载方法
@Override public void write(String dir, String name, OutputStream output, Listener<FileInfo>... listeners) { if (JudgeUtil.isOneNull(dir, name, output)) { return; } File file = getFile(dir, name); if (file.exists()) { InputStream input = null; try { input = FileUtils.openInputStream(file); org.apache.commons.io.IOUtils.copy(input, output); } catch (IOException e) { LOGGER.error(e.getMessage(), e); } finally { try { if (input != null) { input.close(); } if (output != null) { output.close(); } } catch (IOException e1) { LOGGER.error(e1.getMessage(), e1); } } } }
请求下载,设置响应头
ServletOutputStream outputStream = null; try { outputStream = response.getOutputStream(); } catch (IOException ignored) { ; } Assert.notNull(outputStream, "建立传输通道失败"); String apkName = appVersion.getUrl(); response.setHeader("content-type", "application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" + apkName); response.setContentType("application/octet-stream"); xx.write(ROOT_DIR, fileName, outputStream);
设置响应头说明:
'Content-Type': 'application/octet-stream'
表明这是一个二进制文件
'Content-Disposition': 'attachment;filename=req_get_download.js'
表明这是一个需要下载的附件并告诉浏览器默认文件名
Content-Disposition属性有两种类型
inline :将文件内容直接显示在页面
attachment:弹出对话框让用户下载
HTTPS 安全证书问题
1.导入证书。
2.忽略证书:
import javax.net.ssl.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class SslUtil { private static void trustAllHttpsCertificates() throws Exception { TrustManager[] trustAllCerts = new TrustManager[1]; TrustManager tm = new miTM(); trustAllCerts[0] = tm; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, null); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } static class miTM implements TrustManager, X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(X509Certificate[] certs) { return true; } public boolean isClientTrusted(X509Certificate[] certs) { return true; } public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } } /** * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用 */ public static void ignoreSsl() throws Exception{ HostnameVerifier hv = (urlHostName, session) -> true; trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); } }
调用:
try { URL url = new URL(imageUrl); if("https".equalsIgnoreCase(url.getProtocol())){ SslUtil.ignoreSsl(); } inputStream = url.openStream(); // …… } catch(Exception e) { ; } finally { ; }