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这个路径就可以访问了

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在is上被骗了怎么办 微信兼职被骗怎么办天涯论坛 公众号不给稿费怎么办 围绕服务改善民生提出怎么办 翰墨香林苑怎么办全产权 西城高铁联名卡怎么办 英语教学系统做题时超时了怎么办 sci被要求撤稿怎么办 论文投稿后初审通过想撤稿怎么办 河南大学读写译挂了怎么办 在职mba双证硕士怎么办户口 电脑开机了出现一些英文单词怎么办 不懂法语想读法语书怎么办 大鱼号文章需要修改怎么办 过了上诉期怎么办申诉 法院判刑后被告逃亡监护人怎么办 二审判决后不服的怎么办 对树木对生物花草过敏怎么办 高一英语成绩差怎么办 文章被同时录用该怎么办 来不及开ei检索证明怎么办 淘宝生产许可编号一定要填怎么办 官网下单被砍单怎么办美卡美私 大学网络课程挂了怎么办 如果二审超过6个月还不判怎么办? sci的proof时间超了怎么办 合肥电大考试没过怎么办 社保账号密码忘记了怎么办 住房公积金账号密码忘记了怎么办 燃气费单子丢了怎么办 商标初审公告期内被异议怎么办 手被山药痒了怎么办 9个月宝宝不吃奶粉怎么办 八个月宝宝拉粑粑费劲怎么办? 两个月小孩不吃奶粉怎么办 两个月的小孩不吃奶粉怎么办 两个多月宝宝不吃奶怎么办 三个多月宝宝不爱吃奶怎么办 4个月宝宝不吃奶怎么办 5个月宝宝不爱吃奶怎么办 九个月宝宝一直流鼻涕怎么办