通過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);
    }

}

到這里就結束了,試一下吧!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM