(三)springMVC WebUploader分片上传

环境:windows 7
网络:本机或局域网
架构:基于maven的j2ee springMVC
测试结果:可上传620MB左右的文件,如果更大的文件 —> 提示“目标文件”被占用
结论:java拥有跨平台特性,在Api方面不注重方便高效,更多侧重于兼容,对文件无法做到及时有效关闭。
目标:多线程、分片上传,目前无时间安排

1、springMvc 的 servlet加入以下代码(允许上传):

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

2、前端代码片段

引入webuploader css文件,jquery.js文件 webuploader.js 文件,本示例为springMVC,片段代码:

<div id="thelist" class="uploader-list"></div>
                                <div style="margin:20px 20px 20px 0;">
                                    <div id="picker" class="form-control-focus">选择文件</div>
                                </div>
                                <button id="btnSync" type="button" class="btn btn-warning">开始同步</button>
<!-- 省略上面代码 -->
<script>
var uploader = WebUploader.create({

            // swf文件路径
            swf : _ctxRes
                    + '/assets/global/plugins/webuploader-0.1.5/Uploader.swf',

            // 文件接收服务端。
            server : _ctx + '/test-sync/sync',

            chunked : true,

            threads : 1,

            fromData : {
                guid : 'guid'
            },

            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick : '#picker',

            // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize : false
        });

        // 当有文件被添加进队列的时候
        uploader.on('fileQueued', function(file) {
            //alert(123);
            $("#thelist").append(
                    '<div id="' + file.id + '" class="item">'
                            + '<h4 class="info">' + file.name + '</h4>'
                            + '<p class="state">等待上传...</p>' + '</div>');
        });

        uploader.on('uploadSuccess', function(file) {
            $('#' + file.id).find('p.state').text('已上传');
        });

        uploader.on('uploadError', function(file) {
            $('#' + file.id).find('p.state').text('上传出错');
        });

        uploader.on('uploadComplete', function(file) {
            $('#' + file.id).find('.progress').fadeOut();
        });

        $("#btnSync").on('click', function() {
            if ($(this).hasClass('disabled')) {
                return false;
            }
            uploader.options.formData.guid = Math.random();
            uploader.upload();

        });
    </script> </body>

3、服务器端代码

/**
     * 单个文件同步接口
     * 
     * @param request
     * @return
     * @throws JsonGenerationException
     * @throws JsonMappingException
     * @throws IOException
     */
    @SuppressWarnings("resource")
    @RequestMapping(value = "/test-sync/sync", produces = "text/plain;charset=UTF-8")
    @ResponseBody
    public String sync(
            @RequestParam(value = "file", required = false) MultipartFile file,
            HttpServletRequest request, HttpServletResponse response)
            throws JsonGenerationException, JsonMappingException, IOException {


        if (request.getParameter("chunk") == null) {

            String realPath = request.getSession().getServletContext()
                    .getRealPath("/Upload/");
            String fileName = file.getOriginalFilename();

            File targetFile = new File(realPath, fileName);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            file.transferTo(targetFile); // 小文件,直接拷贝

            return "";
        } else {
            int chunk = Integer.parseInt(request.getParameter("chunk")); // 当前分片
            int chunks = Integer.parseInt(request.getParameter("chunks")); // 分片总计

            String realPath = request.getSession().getServletContext()
                    .getRealPath("/Upload/");

            String Ogfilename = file.getOriginalFilename();

            File tempFile = new File(realPath, Ogfilename);
            OutputStream outputStream = new FileOutputStream(tempFile, true);
            InputStream inputStream = file.getInputStream();

            byte buffer[] = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            inputStream.close();
            outputStream.close();

            return "";
        }

    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这里提供一个 Spring MVC + Vue 的大文件分片上传的示例代码: 1. 前端代码(使用 Vue 和 axios 库) ``` <template> <div> <input type="file" @change="handleFileChange"> <button @click="startUpload">开始上传</button> </div> </template> <script> import axios from 'axios' export default { data() { return { file: null, fileChunks: [], currentChunk: 0, uploadProgress: 0 } }, methods: { handleFileChange(e) { this.file = e.target.files[0] this.fileChunks = this.splitFileIntoChunks(this.file) this.currentChunk = 0 this.uploadProgress = 0 }, startUpload() { let formData = new FormData() formData.append('filename', this.file.name) formData.append('totalChunks', this.fileChunks.length) this.uploadChunk(formData) }, uploadChunk(formData) { formData.append('chunk', this.fileChunks[this.currentChunk]) axios.post('/upload', formData, { onUploadProgress: (progressEvent) => { this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total) } }) .then(res => { console.log(res.data) this.currentChunk++ if (this.currentChunk < this.fileChunks.length) { this.uploadChunk(formData) } else { alert('上传成功') } }) .catch(err => { console.log(err) }) }, splitFileIntoChunks(file) { let chunkSize = 1024 * 1024 // 1MB let chunks = [] let start = 0 while (start < file.size) { let end = Math.min(start + chunkSize, file.size) chunks.push(file.slice(start, end)) start += chunkSize } return chunks } } } </script> ``` 2. 后端代码(使用 Spring MVC,处理文件上传) ``` @Controller public class UploadController { private static final String UPLOAD_DIR = "/tmp/uploads/"; @RequestMapping(value = "/upload", method = RequestMethod.POST) @ResponseBody public String upload(@RequestParam("filename") String filename, @RequestParam("totalChunks") int totalChunks, @RequestParam("chunk") MultipartFile chunk) { String chunkFilename = filename + ".part_" + chunk.getOriginalFilename(); String chunkFilepath = UPLOAD_DIR + chunkFilename; if (!chunk.isEmpty()) { try { File file = new File(chunkFilepath); FileUtils.writeByteArrayToFile(file, chunk.getBytes(), true); } catch (IOException e) { e.printStackTrace(); return "上传失败"; } } else { return "上传失败,文件为空"; } if (totalChunks == 1 || totalChunks == FileUtils.listFiles(new File(UPLOAD_DIR), null, false).size()) { // 如果只有一个分片或者所有分片已经上传完毕,则进行文件合并 try { File output = new File(UPLOAD_DIR + filename); FileOutputStream outputStream = new FileOutputStream(output); List<File> files = new ArrayList<>(); for (int i = 0; i < totalChunks; i++) { files.add(new File(UPLOAD_DIR + filename + ".part_" + i)); } Collections.sort(files); for (File file : files) { byte[] bytes = FileUtils.readFileToByteArray(file); outputStream.write(bytes); outputStream.flush(); } outputStream.close(); return "上传成功"; } catch (IOException e) { e.printStackTrace(); return "上传失败"; } } return "分片上传成功"; } } ``` 在前端代码中,我们使用了 input 标签来选择文件,然后使用 splitFileIntoChunks() 方法将文件切割成多个分片,然后使用 axios 库将每个分片上传到后端。在后端代码中,我们使用了 @RequestParam 注解来接收文件信息和分片,然后使用 MultipartFile 对象将分片写入到临时文件中。当所有分片上传完毕时,我们使用 FileUtils 库将所有分片合并成一个文件。需要注意的是,这里的处理文件上传部分需要根据实际需求来进行编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值