文件上傳之Java篇

最近作了一個下載文檔的功能,因而聯想到了上傳功能,因而本身研究了一下後臺語言是java的狀況下怎樣實現將文件上傳到指定的目錄,如下是項目的語言:javascript

一、後臺用jfinal框架css

二、前臺用jquery提交前端

三、樣式用了bootstrap和jqueryjava

中間還由於需求發現了一個不錯的jquery庫,後面會有講解,很少囉嗦了,下面直接開始吧:jquery

1、前端git

一、先添加一個上傳文件的按鈕:github

<button id="upload_blog" type="button" class="btn btn-info btn-lg" >
    <span class="glyphicon glyphicon-upload">上傳</span>
</button>

注意:button和span中的class都是bootstrap中的樣式,直接拿過來用,不過用以前是要引入bootstrap相關樣式的!!!web


二、點擊上傳文件的按鈕彈出一個選擇上傳文件的modal(模態框):ajax

<div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" id="close">&times;</button>
            <h4 class="modal-title">上傳文件</h4>
        </div>
        <div class="modal-body">
            <div id="sizecheck" class="alert alert-danger">
                提示:上傳文件大小不能超過50M!
            </div>
                <form action="" enctype="multipart/form-data" id="upload_file_form" accept="application/msword">
            <span style="display: inline;margin-left: 50px;">請選擇上傳文件:</span><input id="file1" type="file" name="up_blog" style="display: inline;">
            <div id="filecheck" class="alert alert-danger"><strong>Warning!</strong>只能上傳pdf和word兩種類型的文件</div>
            </form>
        </div>
        <div class="modal-footer">
            <button id="yes_blog" type="button" class="btn btn-info">肯定</button>
            <button id="no_blog" type="button" class="btn btn-info" data-dismiss="modal">取消</button>
        </div>
    </div>
    </div>
</div>

上面是彈出的選擇文件的模態框,點擊肯定按鈕會向後臺發送上傳文件的請求:json

三、提交表單,將上傳請求發送到服務器:

$("#upload_blog").click(function(){
        $("#myModal").modal();
        $("#filecheck").attr("hidden","hidden");
        $("#sizecheck").attr("hidden","hidden");
        
        $("#yes_blog").click(function(){
            $("#upload_file_form").ajaxSubmit({
                url:"/blog/uploadFile",
                type:"POST",
                dataType:"json",
                async:false,
                data:{},
                beforeSubmit:function(){
                    //先判斷文件類型--只能上傳word、pdf或txt等文本類型的文件
                    var fileName = $("#file1").val();
                    var extension = fileName.substr(fileName.lastIndexOf("."));
                    if(extension==".pdf" || extension==".doc" || extension==".docx"){
                        $("#filecheck").attr("hidden","hidden");
                    }else{
                        $("#filecheck").removeAttr("hidden");
                        return false;
                    }
                    
                    //判斷上傳文件的大小
                    var fileSize =  $("#file1")[0].files[0].size;
                    //獲取的文件大小單位是比特byte
                    if((fileSize/(1024*1024))>50){
                        $("#sizecheck").removeAttr("hidden");
                        return false;
                    }else{
                        $("#sizecheck").attr("hidden","hidden");
                    }
                },
                success:function(m){
                    if(m.error=="1"){
                        alert(m.message);
                        clearFile();
                        return false;
                    }else{
                        $("#close").trigger("click");
                        toastr.success("文件上傳成功!");
                        clearFile();
                        return true; 
                    }
                }
            });
        });
    });

上面的JS代碼就會將上傳文件的表單提交到後臺,在提交表單以前進行了一系列的驗證:
第一:判斷文件類型,只能上傳word、pdf和txt等文本類型,不然會有提示並阻止表單的提交;

第二:判斷文件的大小是否超過50M,不然會有提示並阻止表單的提交;

2、後臺:

 一、jfinal的controller中完成uploadFile方法:

/**
     * 上傳文件
     * @throws IOException 
     * @throws FileNotFoundException 
     */
    public void uploadFile(){
        /*String fileDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());*/
        UploadFile uploadFile = this.getFile();
        JSONObject jsonObj = new JSONObject();
        String fileName = uploadFile.getFileName();
        File file = uploadFile.getFile();
        String extension = fileName.substring(fileName.lastIndexOf("."));
        String prefix;
        if(extension.equals(".jpg")||extension.equals(".png")||extension.equals(".gif")){
            prefix = "images";
        }else{
            prefix = "docs";
        }
        String filePath = file.getAbsolutePath();
        File targetDir = new File(filePath.substring(0,filePath.indexOf(fileName))+prefix);
        File targetFile = new File(targetDir.getPath()+"/"+fileName);
        if(!targetDir.exists()){
            targetDir.mkdir();
        }
        //字節數組方式上傳文件
        //jsonObj = BlogService.sevice.uploadByByte(filePath, fileName, file, targetFile);
        //通道方式上傳文件
        jsonObj = BlogService.sevice.uploadByChanel(filePath, fileName, file, targetFile);
        renderJson(jsonObj.toJSONString());
    }


注意:在上面的代碼中能夠看到有【字節數組方式上傳文件】和【通道方式上傳文件】,這是我在實現過程當中發現的,並對這兩種方法都作了實現:

二、在service中編寫業務邏輯,有兩種方式:

第一種方式:字節數組方式

/**
     * 使用字節的方式上傳文件
     * @param filePath
     * @param fileName
     * @param sourceFile
     * @param targetFile
     * @return
     */
    public JSONObject uploadByByte(String filePath,String fileName,File sourceFile,File targetFile){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        JSONObject jsonObj = new JSONObject();
        try {
            
            fis = new FileInputStream(sourceFile);
            int fileSize = fis.available();
            fos = new FileOutputStream(targetFile);
            byte[] file_byte = new byte[fileSize];
            if(fis.read(file_byte,0, fileSize)!=-1){
                fos.write(file_byte, 0, fileSize);
            }
            jsonObj.put("error", 0);
            sourceFile.delete();
        } catch (FileNotFoundException e) {
            jsonObj.put("error", 1);
            jsonObj.put("message", "上傳出現錯誤,請稍後再上傳");
        }catch (Exception e) {
            jsonObj.put("error", 1);
            jsonObj.put("message", "文件寫入服務器出現錯誤,請稍後再上傳");
        }finally{
            try {
                fis.close();
                fos.close();
                deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonObj;
    }
View Code

第二種方式:通道方式

/**
     * 使用通道的方式上傳文件
     * @param filePath
     * @param fileName
     * @param sourceFile
     * @param targetFile
     * @return
     */
    public JSONObject uploadByChanel(String filePath,String fileName,File sourceFile,File targetFile){
        JSONObject jsonObj = new JSONObject();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel in = null;
        FileChannel out = null;
        try {
            targetFile.createNewFile();
            fis = new FileInputStream(sourceFile);
            fos = new FileOutputStream(targetFile);
            in = fis.getChannel();//獲得對應的文件通道
            out = fos.getChannel();
            in.transferTo(0,in.size(),out);//鏈接兩個通道,而且從in通道讀取後寫入out通道
            jsonObj.put("error", "0");
        } catch (IOException e) {
            jsonObj.put("error", "1");
            jsonObj.put("message", "文件寫入服務器出錯,請稍後再傳!");
        }finally{
            try {
                fis.close();
                fos.close();
                in.close();
                out.close();
                deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonObj;
    }
View Code

其實兩種方式的差異不是特別大,你們能夠本身研究一下!!
注意:在controller中對文件上傳的位置進行了自定義:

首先Jfinal默認保存路徑是webroot下的upload文件夾,要想保存在本身定義的文件夾中,先要在jfinal中進行配置,若是我要保存在webroot下的/static/upload中就要進行下面的配置:

me.setBaseUploadPath(PathKit.getWebRootPath()+"/static/upload");

而後要根據文件的類型,在自定義路徑下分類建立不一樣的文件夾保存文件。controller中調用service以前的代碼就是作了這個功能:

UploadFile uploadFile = this.getFile();
        JSONObject jsonObj = new JSONObject();
        String fileName = uploadFile.getFileName();
        File file = uploadFile.getFile();
        String extension = fileName.substring(fileName.lastIndexOf("."));
        String prefix;
        if(extension.equals(".jpg")||extension.equals(".png")||extension.equals(".gif")){
            prefix = "images";
        }else{
            prefix = "docs";
        }
        String filePath = file.getAbsolutePath();
        File targetDir = new File(filePath.substring(0,filePath.indexOf(fileName))+prefix);
        File targetFile = new File(targetDir.getPath()+"/"+fileName);
        if(!targetDir.exists()){
            targetDir.mkdir();
        }

最後,會發現即使是本身根據文件類型在默認路徑下定義了新的文件夾,並且文件也會分類保存在相應的文件夾下,可是jfinal仍是會在默認路徑下保存一份文件,這樣同一份文件,在默認路徑下和默認路徑下的自定義路徑中都
保存了一份,以下圖所示:

因此爲了上文件只保存在指定的目錄中,就要作一個刪除upload目錄下的冗餘文件的操做,就是service中調用的deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));這部分,實現以下:

 

    /**
     * 刪除默認路徑下的文件
     * @param file
     */
    public void deleteAllFile(File file){
            File[] files = file.listFiles();
            for(int i=0;i<files.length;i++){
                File filei = files[i];
                if(filei.isFile()){
                    filei.delete();
                }
            }
    }


以上全部步驟就完成了一次上傳文件到指定目錄的功能,下面說一下剛開始說的發現的有趣的jquery庫,能夠在提交表單的代碼中看到這麼一句:

toastr.success("文件上傳成功!");

其實這是一個提示框,並且能夠設置自動消失,避免用戶知道本身操做成功以後還要手動關閉提示框的操做,下面說一下這個技術的實現:
第一步:下載相關的包,並引入相關文件:

只要搜索toastr.js下載就會找到github資源路徑,下載壓縮包,解壓後找到這幾個文件:

不必定都能用到,可是都放在lib裏,以備不時之需,我在這裏只用到了這幾個:

<link rel="stylesheet" type="stylesheet" href="../../static/js/lib/bootstrap/css/message/toastr.min.css">
<link rel="stylesheet" type="stylesheet" href="../../static/js/lib/bootstrap/css/message/messenger.css">
<script type="text/javascript" src="../../static/js/lib/bootstrap/js/message/messenger.min.js?v=${version}"></script>
<script type="text/javascript" src="../../static/js/lib/bootstrap/js/message/messenger-theme-future.js?v=${version}"></script>

第二步:使用前進行配置:

 

/*提示框配置  */
    toastr.options = {
            /* closeButton:false,//是否配置關閉按鈕
            debug:false,//是否開啓debug模式
            neweastOnTop:false,//新消息是否排在最上面
            progressBar:false,//是否顯示進度條
            preventDuplicates:false,//是否阻止彈出多個消息框
            onclick:null,//點擊回調函數
            showDuration:"300",//顯示動做時間
            hideDuration:"300",//隱藏動做時間 */
            positionClass: "toast-center",//消息框的顯示的位置
            timeOut:"1000",//自動關閉的超時時間,即1秒後關閉
            /* extentedTimeOut:"1000",
            showEasing:"swing",
            hideEasing:"liner",
            showMethod:"fadeIn",//顯示的方式
            hideMethod: "fadeOut",//關閉的方式 */
    }

上面是全部配置信息以及做用的解釋,值得注意的是,positionClasss屬性,默認的值有:

能夠看到,這些屬性值中,提示框的位置都是在邊緣,沒有在中間的,因此我就自定義了一個處於中間位置的class:toaster-center

你們也能夠根據本身的頁面屬性自定義 !!

配置完以後就是使用了,其實使用起來很簡單,就一句代碼的事:

toastr.success("文件上傳成功!");

success方式只是定義了彈出框的背景顏色,總共有四種方式:
一、success成功:綠色

二、info信息:藍色

三、warning警告:橙色

四、error錯誤:深紅色

這個顏色的標準跟bootstrap中是同樣的!

以上就是本次文件上傳的全部代碼,以及延伸jquery庫的介紹,下次會介紹後臺語言選擇PHP的狀況下的文件上傳,今天就到此爲止吧,擡頭髮現,人都走了,我也該下班去鍛鍊身體了!

相關文章
相關標籤/搜索