1. 程式人生 > >實際應用一:基於servlet和JavaScript FileReader實現簡單的檔案上傳

實際應用一:基於servlet和JavaScript FileReader實現簡單的檔案上傳

在web專案中檔案上傳是十分平常的,對於檔案上傳之前用過幾種方法都比較實用。

一、基於Apache common fileupload

二、基於servlet和JavaScript FileReader

三、框架裡自帶的檔案上傳

他們各自適用於不同的場合個人認為:第一種適合較大的檔案上傳,第二種適合圖片上傳並且可以上傳預覽但不相容所有瀏覽器,第三種就是你用到ssm、ssh、springboot框架時適用

今天我們先講第二、基於servlet和JavaScript FileReader

1、首先我們先了解下FileReader

FileReader介面提供了一個非同步API,使用該API可以在瀏覽器主執行緒中非同步訪問檔案系統,讀取檔案中的資料。到目前為止,只有FF3.6+和Chrome6.0+實現了FileReader介面。

FileReader介面的方法

FileReader介面有4個方法,其中3個用來讀取檔案,另一個用來中斷讀取。無論讀取成功或失敗,方法並不會返回讀取結果,這一結果儲存在result屬性中。

FileReader介面的方法
方法名 引數 描述
readAsBinaryString file 將檔案讀取為二進位制編碼
readAsText file,[encoding] 將檔案讀取為文字
readAsDataURL file 將檔案讀取為DataURL
abort (none) 終端讀取操作

FileReader介面事件

FileReader介面包含了一套完整的事件模型,用於捕獲讀取檔案時的狀態。

 

FileReader介面的事件
事件 描述
onabort 中斷
onerror 出錯
onloadstart 開始
onprogress 正在讀取
onload 成功讀取
onloadend 讀取完成,無論成功失敗

2、實際演示通過FileReader介面的方法我們怎麼獲取圖片檔案

<!--新增一個檔案輸入框並賦予一個事件我這裡採用onchange你也可以用別的-->
<input type="file" id="inputBox" onchange="selectFile('inputBox','15574478888','1','xx')">

<script>

    <!--函式本身你可以多傳入幾個資訊用於不同的操作或判斷這個人是否可以上傳
        yourinputID:上面那個檔案輸入框,即他的id值;
        account:上傳人的賬號;
        operation:運算元我是將1設為新增,2設為刪除
        name:只用刪除時用到,它為刪除的檔名

    -->
    function selectFile(yourinputID,account,operation,name) {
        var type = null;
        var data = null;

        var inputBox = document.getElementById(yourinputID);

       
            var reader = new FileReader();
            <!--如果輸入框的檔案不為空,則讀取檔案-->
            if (inputBox.files[0] != null) {
                reader.readAsDataURL(inputBox.files[0]);//發起非同步請求
                reader.onload = function () {

                    <!--獲取檔案的型別和資料-->
                    var type = this.result.substring(0, this.result.indexOf("base64") - 1).split("/")[1];
                    var data = this.result.substring(this.result.indexOf("base64") + 7, this.result.length);
                    console.info(this.result);
                    console.info(type);
                    console.info(data);

                     <!--型別和資料不為空時則傳送給後臺-->
                    if(type!=null&&data!=null){
                        $.ajax({
                            //servlet url
                            url : "請求的servlet",
                            //請求方式get、post
                            type : 'post',
                            //向後臺傳送的資料
                            data: {'type': type,'data':data,'account':account,'operation':operation,"name":name},
                            //傳送的資料格式
                            dataType : 'json',
                            success : function(result) {
								console.info(result);
                            }
                        });
                    }
                }
            }
        
    }
</script>

var type = this.result.substring(0, this.result.indexOf("base64") - 1).split("/")[1];
var data = this.result.substring(this.result.indexOf("base64") + 7, this.result.length);

對於前端js程式碼大家可能或不清楚為什麼要進行字串的擷取。這是因為FileReader是將檔案讀取成base64格式。

 

base64(百度百科)

Base64是網路上最常見的用於傳輸8Bit位元組碼的編碼方式之一,Base64就是一種基於64個可列印字元來表示二進位制資料的方法。可檢視RFC2045~RFC2049,上面有MIME的詳細規範。

Base64編碼是從二進位制到字元的過程,可用於在HTTP環境下傳遞較長的標識資訊。例如,在Java Persistence系統Hibernate中,就採用了Base64來將一個較長的唯一識別符號(一般為128-bit的UUID)編碼為一個字串,用作HTTP表單和HTTP GET URL中的引數。在其他應用程式中,也常常需要把二進位制資料編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base64編碼具有不可讀性,需要解碼後才能閱讀。

 

簡單來說他就是一種檔案的表示形勢和二進位制類似

 

我先執行下完整的專案觀察一下:

第一段輸出為:console.info(this.result);

第二段輸出為:console.info(type);

第三段輸出為:console.info(data);

上述輸出即為處理好後的資料。

那沒擷取之前他表示的形式是這樣的:

data:image/png;base64,iVBORAAAANSUhEUg.....

data:image/png;base64,iVBORw0KGgoAAACA.....

data:image/png;宣告型別

base64:宣告格式

所以我們會有字元的擷取

var type = this.result.substring(0, this.result.indexOf("base64") - 1).split("/")[1];(獲取圖片是什麼格式的例如:png、jpg、jpeg。。。)
var data = this.result.substring(this.result.indexOf("base64") + 7, this.result.length);(獲取圖片具體內容)

 

明白這裡那就簡單了,我們只需要將這些資料傳送給後臺就可以了。

 

3.編輯後臺servlet

後臺沒什麼好說的就是獲取引數;base64解碼;建立對應的檔案;新增成功後將圖片url返回;

package com.lb.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Calendar;

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("/Allimg")
public class Allimg extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
     
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("111");
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8;");
		PrintWriter outInfo = response.getWriter();
		
		String account = request.getParameter("account").trim();
		String operation = request.getParameter("operation").trim();
		String name = request.getParameter("name").trim();
		String type = request.getParameter("type").trim();
		String data = request.getParameter("data").trim();
		
		
		sun.misc.BASE64Decoder base64Decoder = new sun.misc.BASE64Decoder();
		System.out.println(request.getServletContext().getRealPath(""));
		
		String path = "/usr/local/nginx/html/FruitImg/";
		Calendar calendar = Calendar.getInstance();
		
		if("1".equals(operation)) {
			File f = new File(path+account+calendar.get(Calendar.MINUTE)+calendar.get(calendar.SECOND)+calendar.get(calendar.MILLISECOND)+"."+type);
			f.createNewFile();
			OutputStream out = new FileOutputStream(f);
			out.write(base64Decoder.decodeBuffer(data));
			out.close();
			
			outInfo.println("{\"url\":"+"\""+account+calendar.get(Calendar.MINUTE)+calendar.get(calendar.SECOND)+calendar.get(calendar.MILLISECOND)+"."+type+"\"}");
			
		}else if("2".equals(operation)) {
			 File file=new File(name);
	         if(file.exists()&&file.isFile()) {
	        	 file.delete();
	        	 outInfo.println("2");
	         }
	             
		}
		
	}

}