zoukankan      html  css  js  c++  java
  • 通过ajax、servlet实现图片的上传功能

    经测试可行,本人上传的地址是要在C盘的目录下建一个"Image"文件夹(当然可以自行创建)

    jsp页面:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <!--这里文件上传实例-->
        <div class="container">
            <div class="panel-heading">分段读取文件:</div>
            <div class="panel-body">
                  <input type="file" id="file" />                  
            </div>
        </div>
    </body>
    <script type="text/javascript">
        /*
         * 分段读取文件为blob ,并使用ajax上传到服务器
         * 分段上传exe文件会抛出异常
         */
        var fileBox = document.getElementById('file');
        file.onchange = function() {
            // 获取文件对象
            var file = this.files[0];
            var reader = new FileReader();
            var step = 1024 * 1024;
            var total = file.size;
            var cuLoaded = 0;
            console.info("文件大小:" + file.size);
            var startTime = new Date();
            // 读取一段成功
            reader.onload = function(e) {
                // 处理读取的结果
                var loaded = e.loaded;
                // 将分段数据上传到服务器
                uploadFile(reader.result, cuLoaded, function() {
                    console.info('loaded:' + cuLoaded + 'current:' + loaded);
                    // 如果没有读完,继续
                    cuLoaded += loaded;
                    if (cuLoaded < total) {
                        readBlob(cuLoaded);
                    } else {
                        console.log('总共用时:'
                                + (new Date().getTime() - startTime.getTime())
                                / 1000);
                        cuLoaded = total;
                    }
                });
            }
            // 指定开始位置,分块读取文件
            function readBlob(start) {
                // 指定开始位置和结束位置读取文件
                // console.info('start:' + start);
                var blob = file.slice(start, start + step);
                reader.readAsArrayBuffer(blob);
            }
            // 开始读取
            readBlob(0);
            // 关键代码上传到服务器
            function uploadFile(result, startIndex, onSuccess) {
                var blob = new Blob([ result ]);
                // 提交到服务器
                var fd = new FormData();
                fd.append('file', blob);
                fd.append('filename', file.name);
                fd.append('loaded', startIndex);
                var xhr = new XMLHttpRequest();
                xhr.open('post', 'http://localhost:8080//uploadtwo/UploadServlet',
                        true);
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // var data = eval('(' + xhr.responseText + ')');
                        console.info(xhr.responseText);
                        if (onSuccess)
                            onSuccess();
                    }
                }
                // 开始发送
                xhr.send(fd);
            }
        }
    </script>
    </html>

    后端UploadServlet:

    package com.servlet;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/UploadServlet")
    public class UploadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            try {
                // 获取客户端传过来图片的二进制流             
                InputStream stream = request.getInputStream();
                // 以当前时间戳为图片命名             
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                String strCurrentTime = df.format(new Date());
                            //最终文件存储位置
                String imagePath = "C://Image/" + strCurrentTime + ".png";
                // 这里的文件格式可以自行修改,如.jpg
                FileOutputStream fos = new FileOutputStream(imagePath);
                byte[] bbuf = new byte[32];
                int hasRead = 0;
                while ((hasRead = stream.read(bbuf)) > 0) {
                    fos.write(bbuf, 0, hasRead);
                    // 将文件写入服务器的硬盘上
                }
                fos.close();
                stream.close();
                /*
                 * 但是需要注意,采用这种原始的方式写入文件时,你会发现被写入的文件内容前4行并非是读取文件的真正内容,            
                 * 从第四行开始才是正文数据。第二行是文件路径以及名称。所以通常的做法是,先将文件写入临时文件中,然后
                 * 再采用RandomAccessFile读取临时文件的第四行以后部分。写入到目标文件中。              
                 */
                Byte n;
                // 读取临时文件           
                RandomAccessFile random = new RandomAccessFile(imagePath, "r");
                int second = 1;
                String secondLine = null;
                while (second <= 2) {
                    secondLine = random.readLine();
                    second++;
                }
                int position = secondLine.lastIndexOf('\');
                // 获取上传文件的名称
                String fileName = secondLine.substring(position + 1, secondLine.length() - 1);
                random.seek(0);
                long forthEndPosition = 0;
                int forth = 1;
                while ((n = random.readByte()) != -1 && (forth <= 4)) {
                    if (n == '
    ') {
                        forthEndPosition = random.getFilePointer();
                        forth++;
                    }
                }
                RandomAccessFile random2 = new RandomAccessFile(imagePath, "rw");
                random.seek(random.length());
                long endPosition = random.getFilePointer();
                long mark = endPosition;
                int j = 1;
                while ((mark >= 0) && (j <= 6)) {
                    mark--;
                    random.seek(mark);
                    n = random.readByte();
                    if (n == '
    ') {
                        endPosition = random.getFilePointer();
                        j++;
                    }
                }
                random.seek(forthEndPosition);
                long startPoint = random.getFilePointer();
                while (startPoint < endPosition - 1) {
                    n = random.readByte();
                    random2.write(n);
                    startPoint = random.getFilePointer();
                }
                random.close();
                random2.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }

    到这里就结束了,试一下吧!!

  • 相关阅读:
    【LeetCode】Hash
    【LeetCode】Heap
    【LeetCode】Stack
    【CodeVS】 纯OI题
    【LeetCode】String
    【LeetCode】Array
    WinForm窗体 常用属性
    C# ADO.NET 实体类中的属性扩展
    C# ADO.NET 三层架构
    C# ADO.NET 数据库的安全(sql 字符串注入攻击、使用占位符防止注入攻击)
  • 原文地址:https://www.cnblogs.com/xslzwm/p/9719720.html
Copyright © 2011-2022 走看看