通过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 == '\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 == '\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);
    }

}

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

posted @ 2018-09-28 17:11  不是一个世界的人  阅读(4147)  评论(0编辑  收藏  举报