5、SpingBoot文件上传、多文件上传、文件下载(断点续传)
来源:互联网 发布:adobe 全套mac破解版 编辑:程序博客网 时间:2024/06/07 01:54
文件上传
SpringBoot的文件上传相对比较简单,文件信息都包含在MultipartFile对象中,只要从中获取文件信息即可
不煽情,直接上代码吧,这个部分出门右拐“百度一下”一大堆
/*** 单文件上传* * @param name 携带的其他文本表单(可以省略)* @param file 文件内容* @return*/@RequestMapping(value = "/upload_single", method = RequestMethod.POST)public @ResponseBody String handleFileUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { BufferedOutputStream out = null; try { byte[] bytes = file.getBytes(); out = new BufferedOutputStream( new FileOutputStream(new File(BASE_PATH + "\\" + name + "-" + file.getOriginalFilename()))); out.write(bytes); return "You successfully uploaded " + name + " into " + name + "-uploaded !"; } catch (Exception e) { return "You failed to upload " + name + " => " + e.getMessage(); } finally { if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } else { return "You failed to upload " + name + " because the file was empty."; }}
测试:
<p>单文件上传</p><form method="POST" enctype="multipart/form-data" action="/upload_single"> File to upload: <input type="file" name="file"/><br /> Name: <input type="text" name="name"/> <input type="submit" value="单文件上传"/></form>
多文件上传
多文件上传需要接收解析出MultipartHttpServletRequest对象中包含的文件信息
/*** 多文件上传,主要是使用了MultipartHttpServletRequest和MultipartFile* * @param name 携带的其他文本表单(可以省略)* @param request* @return*/@RequestMapping(value = "/upload", method = RequestMethod.POST)public @ResponseBody String handleFileUpload(HttpServletRequest request,@RequestParam("name") String name) { List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file"); System.out.println("name==>"+name); MultipartFile file = null; BufferedOutputStream out = null; for (int i = 0; i < files.size(); ++i) { file = files.get(i); if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); out = new BufferedOutputStream(new FileOutputStream(new File(BASE_PATH + "\\" + file.getOriginalFilename()))); out.write(bytes); } catch (Exception e) { return "failed to upload " + i + " => " + e.getMessage(); } finally { if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } out = null; } } } else { return "failed to upload " + i + " because the file was empty."; } } return "upload successful";}
测试:
<p>多文件上传</p><form method="POST" enctype="multipart/form-data" action="/upload"> Name: <input type="text" name="name"/> <p>文件1:<input type="file" name="file" /></p> <p>文件2:<input type="file" name="file" /></p> <p><input type="submit" value="多文件上传" /></p></form>
文件下载(断点续传)
相对于上传在文件下载的处理上,需要自己处理HttpServletResponse中流的返回,这里直接上一个有断点续传的代码:
@RequestMapping(value = "/download", method = RequestMethod.GET)public void getDownload(String name, HttpServletRequest request, HttpServletResponse response) { // Get your file stream from wherever. String fullPath = "D:\\upload_test\\" + name; File downloadFile = new File(fullPath); ServletContext context = request.getServletContext(); // get MIME type of the file String mimeType = context.getMimeType(fullPath); if (mimeType == null) { // set to binary type if MIME mapping not found mimeType = "application/octet-stream"; } // set content attributes for the response response.setContentType(mimeType); // response.setContentLength((int) downloadFile.length()); // set headers for the response String headerKey = "Content-Disposition"; String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName()); response.setHeader(headerKey, headerValue); // 解析断点续传相关信息 response.setHeader("Accept-Ranges", "bytes"); long downloadSize = downloadFile.length(); long fromPos = 0, toPos = 0; if (request.getHeader("Range") == null) { response.setHeader("Content-Length", downloadSize + ""); } else { // 若客户端传来Range,说明之前下载了一部分,设置206状态(SC_PARTIAL_CONTENT) response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); String range = request.getHeader("Range"); String bytes = range.replaceAll("bytes=", ""); String[] ary = bytes.split("-"); fromPos = Long.parseLong(ary[0]); if (ary.length == 2) { toPos = Long.parseLong(ary[1]); } int size; if (toPos > fromPos) { size = (int) (toPos - fromPos); } else { size = (int) (downloadSize - fromPos); } response.setHeader("Content-Length", size + ""); downloadSize = size; } // Copy the stream to the response's output stream. RandomAccessFile in = null; OutputStream out = null; try { in = new RandomAccessFile(downloadFile, "rw"); // 设置下载起始位置 if (fromPos > 0) { in.seek(fromPos); } // 缓冲区大小 int bufLen = (int) (downloadSize < 2048 ? downloadSize : 2048); byte[] buffer = new byte[bufLen]; int num; int count = 0; // 当前写到客户端的大小 out = response.getOutputStream(); while ((num = in.read(buffer)) != -1) { out.write(buffer, 0, num); count += num; //处理最后一段,计算不满缓冲区的大小 if (downloadSize - count < bufLen) { bufLen = (int) (downloadSize-count); if(bufLen==0){ break; } buffer = new byte[bufLen]; } } response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } }}
该部分本人直接在Android客户端上测试:
下载代码:
public static boolean downLoadFile(String url, int from, int to,String savePath) { try { URL link = new URL(url); HttpURLConnection conn = (HttpURLConnection) link.openConnection(); // 设置断点续传的开始位置 if (to != 0) { conn.setRequestProperty("Range", "bytes=" + from + "-" + to); }else{ conn.setRequestProperty("Range", "bytes=" + from + "-"); } Log.e("m_tag", "code:" + conn.getResponseCode()); if (conn.getResponseCode() == 206) { RandomAccessFile file = new RandomAccessFile(savePath, "rw"); file.seek(from); InputStream in = conn.getInputStream(); byte[] buffer = new byte[1024]; int num; while ((num = in.read(buffer)) > 0) { file.write(buffer, 0, num); } file.close(); in.close(); return true; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return false;}
Activity中运用:
class MyTask extends AsyncTask<Object, Integer, Object> { @Override protected Object doInBackground(Object... params) { String uri = (String) params[0]; int from = (Integer) params[1]; int to = (Integer) params[2]; String savePath = (String) params[3]; return HttpUtil.downLoadFile(uri, from, to, savePath); } @Override protected void onPostExecute(Object result) { // TODO Auto-generated method stub super.onPostExecute(result); tvRes.setText(result.toString()); }}//这里用两个按钮点击模拟分段,第一个按钮下载0-50B,第二个从50B下载到末尾...省略其他部分...case R.id.btn_part_01: new MyTask().execute("http://192.168.2.183:8080/download?name=11.jpg",0, 50, "/mnt/sdcard/pic_123.jpg");break;case R.id.btn_part_02: new MyTask().execute("http://192.168.2.183:8080/download?name=11.jpg",50, 0, "/mnt/sdcard/pic_123.jpg");break;...省略其他部分...
[附]
文件上传时相对路径配置
以上的上传文件可以保存到服务器端的D:\upload_test但是对于这个路径,客户端如果想要使用一个相对路径来访问的话,需要做以下配置:
1、在application.properties中声明一个变量描述该地址
#图片上传存储路径imagesPath=file:/D:/upload_test/
2、定义一个配置文件可以将该绝对路径映射到一个/images的相对路径上
package com.example.demo.config;import org.apache.log4j.spi.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class FileConfig extends WebMvcConfigurerAdapter { @Value("${imagesPath}") private String mImagesPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { if (mImagesPath.equals("") || mImagesPath.equals("${imagesPath}")) { String imagesPath = FileConfig.class.getClassLoader().getResource("").getPath(); if (imagesPath.indexOf(".jar") > 0) { imagesPath = imagesPath.substring(0, imagesPath.indexOf(".jar")); } else if (imagesPath.indexOf("classes") > 0) { imagesPath = "file:" + imagesPath.substring(0, imagesPath.indexOf("classes")); } imagesPath = imagesPath.substring(0, imagesPath.lastIndexOf("/")) + "/images/"; mImagesPath = imagesPath; } System.out.println("imagesPath=" + mImagesPath); registry.addResourceHandler("/images/**").addResourceLocations(mImagesPath); super.addResourceHandlers(registry); }}
这样之后对于服务器上D:\upload_test\1.jpg这个图片可以在客户端直接使用http://127.0.0.1:8080/images/1.jpg这个路径就可以访问了
阅读全文
0 0
- 5、SpingBoot文件上传、多文件上传、文件下载(断点续传)
- C# 断点续传 上传、下载文件处理
- C# 断点续传 上传、下载文件处理
- C# 断点续传 上传、下载文件处理
- C# 断点续传 上传、下载文件处理
- AIR文件上传与文件断点续传方式下载
- 上传文件 | 下载文件
- java 文件上传支持断点续传
- android大文件上传断点续传
- 大文件分块上传,断点续传
- curl用ftp方式断点续传下载上传文件
- java支持断点续传文件上传和下载组件
- 4、文件上传_5、多文件上传_6、文件下载
- 文件上传与下载----上传
- 5文件上传与下载
- 多文件上传【下载、删除】
- 多文件上传和下载
- C#实现上传文件分割,断点续传上传文件
- Android 广播大全 Intent Action 事件
- 附近卖家实现2.0
- MongoDB--知识点总结
- java 常用包
- 进程间通信(2):命名管道
- 5、SpingBoot文件上传、多文件上传、文件下载(断点续传)
- 蚂蚁分类短信接口替换
- Android Studio 使用 git 遇到的问题
- Android系统广播大全
- html的checkbox无法勾选
- 如何在csdn的makedown编辑器中将多个图片放在一行
- JAVA安卓开发SP存储
- 有关安卓模拟器停止运行时的解决方案
- 让你快速理解Redux