作为服务端
作为客户端
下载url需要取请求服务端
如果是浏览器访问的话,相当于浏览器帮你做了url的encode是可以下载的
如果用代码的话,一般如下:
public static String downLoadFromUrl(String urlStr, String fileName, String savePath) {try {URL url = new URL(urlStr);HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置超时间为30秒conn.setConnectTimeout(60 * 1000);// 防止屏蔽程序抓取而返回403错误conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");// 得到输入流InputStream inputStream = conn.getInputStream();// 获取自己数组byte[] getData = readInputStream(inputStream);// 文件保存位置File saveDir = new File(savePath);if (!saveDir.exists()) {saveDir.mkdir();}File file = new File(saveDir + File.separator + fileName);FileOutputStream fos = new FileOutputStream(file);fos.write(getData);if (fos != null) {fos.close();}if (inputStream != null) {inputStream.close();}return saveDir + File.separator + fileName;} catch (Exception e) {e.printStackTrace();}return "";}
第十行会报错FileNotFound.类似这样
java.io.FileNotFoundException: http://www.zzgcjyzx.com:8087/Front/AttachStorage/202101/J070/ff6ee790-137a-4807-bab0-6622339e0321/[E3506010601800136042001]国泰新点测试项目20210118新接口测试项目-1.ZZZFat sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1896)at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)at com.dfit.api.junziqian.service.SignFileUtils.downLoadFromUrl(SignFileUtils.java:29)at com.dfit.api.basic.controller.ProcessControllerTest.t2(ProcessControllerTest.java:55)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
解决办法
方法1:url特殊部分进行encode
@Testpublic void t3() throws Exception {String a = "http://www.zzgcjyzx.com:8087/Front/AttachStorage/202101/J070/ff6ee790-137a-4807-bab0-6622339e0321/";String b = "[E3506010601800136042001]国泰新点测试项目20210118新接口测试项目-1.ZZZF";String realUrl=a+URLEncoder.encode(b,"UTF-8");System.out.println(realUrl);String fileName = StringUtils.substringAfterLast(urls,"/");SignFileUtils.downLoadFromUrl(realUrl, fileName, fileDir);}
方法2:用http直接请求
hutool请求
String urls = "http://www.zzgcjyzx.com:8087/Front/AttachStorage/202101/J070/ff6ee790-137a-4807-bab0-6622339e0321/[E3506010601800136042001]国泰新点测试项目20210118新接口测试项目-1.ZZZF";String fileDir = "d:/filestore/";@Testpublic void t1() throws Exception {String fileName = StringUtils.substringAfterLast(urls,"/");HttpUtil.downloadFile(urls, fileDir+fileName);}
总结
两种思路都有一定局限性
方法1好像不知道特殊的符号在哪里
方法2暂时还不知道有啥问题
方法1优化:
HuTool URLUtil的方法可以帮我们对url进行转义public static String normalize(String url, boolean isEncodePath) {if (StrUtil.isBlank(url)) {return url;}final int sepIndex = url.indexOf("://");String protocol;String body;if (sepIndex > 0) {protocol = StrUtil.subPre(url, sepIndex + 3);body = StrUtil.subSuf(url, sepIndex + 3);} else {protocol = "http://";body = url;}final int paramsSepIndex = StrUtil.indexOf(body, '?');String params = null;if (paramsSepIndex > 0) {params = StrUtil.subSuf(body, paramsSepIndex);body = StrUtil.subPre(body, paramsSepIndex);}if (StrUtil.isNotEmpty(body)) {// 去除开头的\或者///noinspection ConstantConditionsbody = body.replaceAll("^[\\\\/]+", StrUtil.EMPTY);// 替换多个\或/为单个/body = body.replace("\\", "/").replaceAll("//+", "/");}final int pathSepIndex = StrUtil.indexOf(body, '/');String domain = body;String path = null;if (pathSepIndex > 0) {domain = StrUtil.subPre(body, pathSepIndex);path = StrUtil.subSuf(body, pathSepIndex);}if (isEncodePath) {path = encode(path);}return protocol + domain + StrUtil.nullToEmpty(path) + StrUtil.nullToEmpty(params);}
在方法1放url的地方,对url部分进行转义即可,还是同事老哥厉害
