Java通过HttpClient从外部url下载文件到本地

短命女 2023-10-04 15:21 100阅读 0赞
目标
1.将外网文件通过url转化成本地文件

如百度logo图片,右键复制图片链接https://www.baidu.com/img/flexible/logo/pc/result.png
在这里插入图片描述
通过代码将图片下载到本地
在这里插入图片描述

2.解决图片防盗链问题

在这里插入图片描述
防盗链如上图展示,那什么是盗链,什么是防盗链?

盗链

盗链是指在自己的网站页面上展示一些并不在自己服务器上的内容。

大白话就是自己的网站上的资源,如图片,视频等链接在别人的网址中出现,则流量和服务器压力都是走的我们自己的电脑,造成服务器压力和流量流失。

防盗链

防止别人通过一些技术手段绕过本站的资源展示页面,盗用本站的资源,让从非本站资源展示页面的资源链接失效,保证流量没必要流失。

大白话就是通过Referer或者签名来保证访问的资源都是统一站点,保证来源一致。

上代码
  1. package com.haier.healthroom.kefu.utils;
  2. import org.apache.commons.lang3.StringUtils;
  3. import org.apache.http.*;
  4. import org.apache.http.client.HttpClient;
  5. import org.apache.http.client.methods.HttpGet;
  6. import org.apache.http.impl.client.HttpClients;
  7. import java.io.File;
  8. import java.io.FileOutputStream;
  9. import java.io.InputStream;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. import java.util.regex.Matcher;
  13. import java.util.regex.Pattern;
  14. /**
  15. * 一个低端小气没档次的程序狗 JavaDog
  16. * blog.javadog.net
  17. *
  18. * @BelongsProject: healthroom
  19. * @BelongsPackage: com.haier.healthroom.kefu.utils
  20. * @Author: hdx
  21. * @CreateTime: 2021-06-04 10:10
  22. * @Description: HttpDownload
  23. */
  24. public class HttpDownloadUtil {
  25. public static final int cache = 10 * 1024;
  26. public static void main(String[] args) {
  27. String url = "https://www.baidu.com/img/flexible/logo/pc/result.png";
  28. String targetUrl = "E:\\demo\\";
  29. HttpDownloadUtil.download(url,targetUrl);
  30. }
  31. /**
  32. * 根据url下载文件,保存到filepath中
  33. *
  34. * @param url
  35. * @param diskUrl
  36. * @return
  37. */
  38. public static String download(String url, String diskUrl) {
  39. String filepath = "";
  40. String filename = "";
  41. try {
  42. HttpClient client = HttpClients.createDefault();
  43. HttpGet httpget = new HttpGet(url);
  44. // 加入Referer,防止防盗链
  45. httpget.setHeader("Referer", url);
  46. HttpResponse response = client.execute(httpget);
  47. HttpEntity entity = response.getEntity();
  48. InputStream is = entity.getContent();
  49. if (StringUtils.isBlank(filepath)){
  50. Map<String,String> map = getFilePath(response,url,diskUrl);
  51. filepath = map.get("filepath");
  52. filename = map.get("filename");
  53. }
  54. File file = new File(filepath);
  55. file.getParentFile().mkdirs();
  56. FileOutputStream fileout = new FileOutputStream(file);
  57. byte[] buffer = new byte[cache];
  58. int ch = 0;
  59. while ((ch = is.read(buffer)) != -1) {
  60. fileout.write(buffer, 0, ch);
  61. }
  62. is.close();
  63. fileout.flush();
  64. fileout.close();
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. }
  68. return filename;
  69. }
  70. /**
  71. * 根据contentType 获取对应的后缀 (列出常用的ContentType对应的后缀)
  72. *
  73. * @param contentType
  74. * @return
  75. */
  76. static String getContentType(String contentType){
  77. HashMap<String, String> map = new HashMap<String, String>() {
  78. {
  79. put("application/msword", ".doc");
  80. put("image/jpeg", ".jpeg");
  81. put("application/x-jpg", ".jpg");
  82. put("video/mpeg4", ".mp4");
  83. put("application/pdf", ".pdf");
  84. put("application/x-png", ".png");
  85. put("application/x-ppt", ".ppt");
  86. put("application/postscript", ".ps");
  87. put("application/vnd.android.package-archive", ".apk");
  88. put("video/avi", ".avi");
  89. put("text/html", ".htm");
  90. put("image/png", ".png");
  91. put("application/x-png", ".png");
  92. put("image/gif", ".gif");
  93. }
  94. };
  95. return map.get(contentType);
  96. }
  97. /**
  98. * 获取response要下载的文件的默认路径
  99. *
  100. * @param response
  101. * @return
  102. */
  103. public static Map<String,String> getFilePath(HttpResponse response, String url, String diskUrl) {
  104. Map<String,String> map = new HashMap<>();
  105. String filepath = diskUrl;
  106. String filename = getFileName(response, url);
  107. String contentType = response.getEntity().getContentType().getValue();
  108. if(StringUtils.isNotEmpty(contentType)){
  109. // 获取后缀
  110. String suffix = getContentType(contentType);
  111. String regEx = ".+(.+)$";
  112. Pattern p = Pattern.compile(regEx);
  113. Matcher m = p.matcher(filename);
  114. if (!m.find()) {
  115. // 如果正则匹配后没有后缀,则需要通过response中的ContentType的值进行匹配
  116. if(StringUtils.isNoneBlank(suffix)){
  117. filename = filename + suffix;
  118. }
  119. }else{
  120. if(filename.length()>20){
  121. filename = getRandomFileName() + suffix;
  122. }
  123. }
  124. }
  125. if (filename != null) {
  126. filepath += filename;
  127. } else {
  128. filepath += getRandomFileName();
  129. }
  130. map.put("filename", filename);
  131. map.put("filepath", filepath);
  132. return map;
  133. }
  134. /**
  135. * 获取response header中Content-Disposition中的filename值
  136. * @param response
  137. * @param url
  138. * @return
  139. */
  140. public static String getFileName(HttpResponse response,String url) {
  141. Header contentHeader = response.getFirstHeader("Content-Disposition");
  142. String filename = null;
  143. if (contentHeader != null) {
  144. // 如果contentHeader存在
  145. HeaderElement[] values = contentHeader.getElements();
  146. if (values.length == 1) {
  147. NameValuePair param = values[0].getParameterByName("filename");
  148. if (param != null) {
  149. try {
  150. filename = param.getValue();
  151. } catch (Exception e) {
  152. e.printStackTrace();
  153. }
  154. }
  155. }
  156. }else{
  157. // 正则匹配后缀
  158. filename = getSuffix(url);
  159. }
  160. return filename;
  161. }
  162. /**
  163. * 获取随机文件名
  164. *
  165. * @return
  166. */
  167. public static String getRandomFileName() {
  168. return String.valueOf(System.currentTimeMillis());
  169. }
  170. /**
  171. * 获取文件名后缀
  172. * @param url
  173. * @return
  174. */
  175. public static String getSuffix(String url) {
  176. // 正则表达式“.+/(.+)$”的含义就是:被匹配的字符串以任意字符序列开始,后边紧跟着字符“/”,
  177. // 最后以任意字符序列结尾,“()”代表分组操作,这里就是把文件名做为分组,匹配完毕我们就可以通过Matcher
  178. // 类的group方法取到我们所定义的分组了。需要注意的这里的分组的索引值是从1开始的,所以取第一个分组的方法是m.group(1)而不是m.group(0)。
  179. String regEx = ".+/(.+)$";
  180. Pattern p = Pattern.compile(regEx);
  181. Matcher m = p.matcher(url);
  182. if (!m.find()) {
  183. // 格式错误,则随机生成个文件名
  184. return String.valueOf(System.currentTimeMillis());
  185. }
  186. return m.group(1);
  187. }
  188. }
测试

运行main方法
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,100人围观)

还没有评论,来说两句吧...

相关阅读