1. 程式人生 > >檔案的上傳,核心API的使用,檔案下載,註解(jdk的註解、自定義註解)

檔案的上傳,核心API的使用,檔案下載,註解(jdk的註解、自定義註解)

第一部分:檔案的上傳

1、什麼是檔案的上傳

1.1 把本地的檔案儲存到伺服器上,這個過程稱為檔案的上傳。比如,網盤、qq空間

1.2 實現檔案的上傳
(1)jspSmartUpload:應用在jsp的模型一
= 適於嵌入執行上傳下載操作的JSP檔案中

(2)fileUpload:應用在jsp的模型二(mvc)
= FileUpload 是 Apache commons下面的一個子專案
= 元件FileUpload依賴於Commons IO元件
= 匯入jar包(有兩個jar包)

(3)要想使用第三方的技術實現檔案的上傳,首先匯入jar包

1.3 要想使用檔案的上傳,滿足三個要求
第一個要求:表單,提交方式是post
    = get提交方式:位址列會攜帶資料,get大小有限制

第二個要求:在表單裡面有檔案上傳項,必須有name屬性 <input type="file" name="filename"/>

第三個要求:在form裡面,設定一個屬性值 enctype,設定為multipart/form-data

2、使用程式碼實現檔案的上傳

2.1 檔案上傳程式碼實現的步驟(固定)
第一步:建立磁碟檔案項工廠
= new DiskFileItemFactory();
第二步:建立核心上傳類
= new ServletFileUpload(FileItemFactory fileItemFactory);
第三步:使用核心上傳類解析request物件
= parseRequest(javax.servlet.http.HttpServletRequest request)
= 返回的List集合,集合裡面有多個FileItem,List<FileItem>
第四步:遍歷list集合,得到每個FileItem
第五步:判斷是普通輸入項還是檔案上傳項
= boolean isFormField()
第六步:如果是普通輸入項得到值;如果是檔案上傳項編寫上傳的程式碼
= 普輸入項
== getFieldName():得到普通輸入項name的屬性的值
== getString():得到普通輸入項裡面輸入的值
= 檔案上傳項
== 得到通過表單提交過了的檔案的輸入流,getInputStream()
== 建立輸出流,把檔案的輸入流寫到伺服器的一個檔案中

3、核心api的使用

3.1 DiskFileItemFactory:磁碟檔案項工廠
(1)構造方法
= DiskFileItemFactory(int sizeThreshold, java.io.File repository)
== 有兩個引數:
== 第一個引數設定上傳檔案的緩衝區的大小;
== 第二個引數是如果上傳檔案超出了緩衝區,產生臨時檔案,設定臨時檔案路徑

= DiskFileItemFactory()
== setSizeThreshold(int sizeThreshold):設定上傳檔案的緩衝區的大小
== setRepository(java.io.File repository):設定臨時檔案路徑


3.2 ServletFileUpload:核心上傳類
(1)構造方法
= ServletFileUpload(FileItemFactory fileItemFactory)

(2)普通方法
= parseRequest(javax.servlet.http.HttpServletRequest request):解析request物件
返回List集合,集合裡面每個部分是FileItem

= setHeaderEncoding(java.lang.String encoding):設定上傳檔名稱的編碼

= setFileSizeMax(long fileSizeMax):設定單個上傳檔案的大小

= setSizeMax(long sizeMax):設定上傳檔案的總大小


3.3 FileItem:檔案項
(1)普通方法
= boolean isFormField():判斷是否是普通輸入項,返回boolean,如果返回true是普通輸入項

= getFieldName():得到普通輸入項name的屬性值

= getString():得到普通輸入項輸入的值
= getString(java.lang.String encoding):輸入的值有中文,設定編碼

= getName():得到上傳檔案的名稱。在某些瀏覽器裡面得到帶路徑的名稱,擷取操作

= getInputStream():得到表單提交的檔案的輸入流

= delete():刪除臨時檔案

4、練習:js控制多檔案的上傳

4.1 需求描述
(1)在上傳表單裡面,有兩個按鈕,一個是上傳,一個是增加
(2)點選增加按鈕時候,增加一個檔案上傳項和刪除按鈕
(3)點選刪除按鈕時候,刪除一行內容
(4)點選上傳按鈕時候,把當前檔案上傳到伺服器

4.2 使用js增加一行和刪除一行
(1)程式碼
    //增加一行
    function addFile() {
        //得到div
        var div1 = document.getElementById("div1");
        div1.innerHTML += "<div><input type='file' name='filename'/><input type='button' value='刪除' onclick='del1(this);'/></div>";
    }

    //刪除一行
    function del1(who) {
        //因為要刪除檔案上傳項和刪除按鈕,這兩個內容都在div裡面,刪除div就可以了
        //得到當前點選的刪除按鈕所在的div
        var div = who.parentNode;
        //刪除div,使用dom裡面的方法 removeChild(),不能自己刪除自己,通過父標籤刪除
        //得到要刪除div的父標籤
        var div1 = div.parentNode;
        div1.removeChild(div);
    }

4.3 使用button提交表單
(1)程式碼
    //提交表單,實現上傳(使用button提交的表單)
    function uploadfile() {
        //得到form標籤
        var form1 = document.getElementById("form1");
        form1.submit();
    }

5、檔案上傳問題的解決

5.1 檔案重名的問題
(1)如果上傳了多個專案名稱的檔案,最後一次上傳的檔案,把之後的檔案給覆蓋了。

5.2 解決方法
(1)在上傳的檔名稱裡面,新增一個隨機的唯一的字串,保證每個檔名稱都是唯一的一個值
(2)生成一個隨機的唯一的值
第一種方式:使用毫秒數實現
第二種方式:使用UUID工具類實現
(3)程式碼
    //在檔名稱裡面新增隨機的唯一的值
    String uuid = UUID.randomUUID().toString();
    //uuid_filename
    filename = uuid+"_"+filename;

第二部分:檔案的下載

1、什麼是檔案的下載

1.1 把伺服器上檔案儲存到本地硬碟,這個過程稱為檔案的下載

1.2 檔案下載的實現方式:有兩種實現方式
第一種方式:使用超連結實現檔案的下載 
(1)如果要下載的檔案是圖片格式,直接在瀏覽器裡面開啟;如果下載的是zip格式的檔案,才會
提示下載。最終:無論什麼格式都是一下載方式開啟。

第二種方式:通過程式碼實現檔案的下載
(1)實現的步驟
第一步:設定要下載檔案的MIME型別,設定頭資訊 Content-Disposition,無論是什麼格式,都是以下載方式開啟
第二步:從伺服器上得到要下載的檔案的輸入流
第三步:建立輸出流,通過輸出流把檔案寫到瀏覽器
第四步:流對接,關閉流

2、程式碼實現檔案的下載

2.1 實現的步驟
第一步:設定要下載檔案的MIME型別,設定頭資訊 Content-Disposition,無論是什麼格式,都是以下載方式開啟
= 設定mime型別
    //設定要下載檔案的mime型別
    String type = getServletContext().getMimeType(filename);
    //設定mime型別
    response.setContentType(type);
= 設定頭資訊
    response.setHeader("Content-Disposition", "attachment;filename="+filename);

第二步:從伺服器上得到要下載的檔案的輸入流
    //得到要下載檔案的輸入流
    InputStream in = new FileInputStream(path);

第三步:建立輸出流,通過輸出流把檔案寫到瀏覽器
    OutputStream out = response.getOutputStream();

第四步:流對接,關閉流


2.2 下載檔名稱包含中文的亂碼問題解決
(1)不同的瀏覽器有不同的編碼,ie瀏覽器採用的url編碼,火狐採用base64編碼
(2)區分不同的瀏覽器
= 在請求頭 User-Agent,得到當前請求的瀏覽器的型別
(3)程式碼
    //得到當前請求的瀏覽器型別 ,使用頭 User-Agent
    String agent = request.getHeader("User-Agent");
    if(agent.contains("Firefox")) {//如果是火狐瀏覽器
        //base64編碼
        filename = "=?UTF-8?B?"+
                new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
    } else {
        //url編碼
        filename = URLEncoder.encode(filename, "UTF-8");
    }

第三部分:註解

1、什麼是註解

1.1 是jdk5.0的新特性
(1)jdk5.0很多新特性:泛型、自動拆裝箱、增強for迴圈、可變引數、列舉..

1.2 註解不是註釋
(1)註釋:給程式設計師看的
(2)註解:給程式看的
(3)註解就是程式碼裡面的特殊標記,主要功能替代配置檔案
其實就是程式碼裡的特殊標記, 它用於替代配置檔案,
也就是說,傳統方式通過配置檔案告訴類如何執行,
有了註解技術後,開發人員可以通過註解告訴類如何執行。
在Java技術裡註解的典型應用是:可以通過反射技術去得到類裡面的註解,以決定怎麼去執行類。

1.3 寫法
(1) @註解的名稱
(2)可以使用在方法上面,也可以是類上面

2、jdk裡面的三個註解

(1) @Override: 限定重寫父類方法, 該註解只能用於方法

(2) @SuppressWarnings: 抑制編譯器警告.
= @SuppressWarnings("all")
= 不影響程式的執行

(3) @Deprecated: 用於表示某個程式元素(類, 方法等)已過時
= 不影響程式的執行

3、自定義註解

3.1 定義的方式:使用關鍵字 @interface 註解名稱
(1) @interface MyAnno { }

3.2 宣告註解的屬性
(1)型別 屬性的名稱();
@interface MyAnno {
    //定義屬性
    String aa();    
    int bb();
}

3.3 如果定義屬性型別是Date型別,報錯
Invalid type Date for the annotation attribute MyAnno.date; 
only primitive type, String, Class, annotation, enumeration are permitted 
or 1-dimensional arrays thereof

(1)屬性允許的型別:基本資料型別、string、Class、註解、列舉,一維陣列
(2)程式碼
//自定義註解
@interface MyAnno {
    //定義屬性
    String aa();    
    int bb();

    //定義Date型別
//  Date date();

    //定義Class型別
    Class clazz();

    //定義註解
    anno ann();

    //定義列舉型別
    Color c();

    //定義一維陣列
    String[] arr();
}

(3)使用自定義註解
@MyAnno(aa="qq",bb=1,clazz=TestAnno01.class,[email protected],c=Color.RED,arr={"aa","bb"})

3.4 特殊屬性value
(1)如果把屬性的名稱寫成value,在使用這個註解的時候value可以省略不寫

3.5 元註解
(1)修飾註解的註解
@Retention:修飾註解使用範圍,自定義一個註解,在預設的情況下是原始碼階段
    RetentionPolicy.CLASS: 編譯器將把註解記錄在 class 檔案中. 當執行 Java 程式時, JVM 不會保留註解. 這是預設值
    RetentionPolicy.RUNTIME:編譯器將把註釋記錄在 class 檔案中. 當執行 Java 程式時, JVM 會保留註解. 程式可以通過反射獲取該註釋
    RetentionPolicy.SOURCE: 編譯器直接丟棄這種策略的註釋

    @Retention(RetentionPolicy.RUNTIME)

@Target:指定註解用於修飾類的哪個成員. 
    @Target 包含了一個名為  value,型別為ElementType的成員變數。 
    @Target({ElementType.METHOD,ElementType.PARAMETER})

@Documented: 用於指定被該元 Annotation 修飾的 Annotation 類將被 javadoc 工具提取成文件.

@Inherited: 被它修飾的 Annotation 將具有繼承性.
    如果某個類使用了被 @Inherited 修飾的 Annotation, 則其子類將自動具有該註解

4、使用反射+註解完成兩個練習

4.1 使用反射+註解實現模擬單元測試的效果
(1)什麼是單元測試 junit
= 測試一個類中的方法,使用註解方式進行操作 @Test
= 在要測試方法上面添加註解 @Test,選擇要測試的方法,點選右鍵 run as ---> junit  test
= 執行之後,在工具裡面出現一個JUNIT,有一個綠色的條,表示測試通過了
= 執行之後,在工具裡面出現一個JUNIT,如果有紅棕色條,表示測試失敗
= 在方法上面有 @Test註解,這個方法就可以執行
= @Ignore :當前的方法不參與單元測試

(2)實現的步驟
 * 1、得到要測試方法所在類的Class
 *  = 有三種方式
 *  第一種:類名.class
 *  第二種:物件.getClass()
 *  第三種:Class.forName("包類路徑")
 * 2、得到類中的所有的方法
 *  Method[] getMethods()  ,返回方法的陣列
 * 3、遍歷陣列,得到類中的每個方法
 * 4、判斷方法上面是否有註解
 *  boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 
 *  = 引數:註解的Class
 * 5、如果有註解,讓方法執行
 *  invoke(Object obj, Object... args) 
 *  = 第一個引數是類例項;第二個引數執行方法裡面的引數

(3)自定義的註解,在預設情況下作用範圍是原始碼階段,使用元註解設定的作用範圍

(4)程式碼
    //得到要測試方法所在類的Class
    Class clazz = TestJunit02.class;
    //得到類中的所有的方法
    Method[] methos = clazz.getMethods();
    //遍歷陣列,得到每個方法
    for (Method m : methos) {
        //判斷方法上面是否有註解
        //自定義註解,在預設情況下作用在原始碼階段
        //使用元註解修飾註解的作用範圍  @Retention(RetentionPolicy.RUNTIME)
        boolean flag = m.isAnnotationPresent(MyTest.class);
        //如果有註解,讓方法執行
        if(flag) {
            //方法執行 invoke()
            try {
                m.invoke(clazz.newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }


4.2 使用反射獲取註解裡面的屬性值
(1)使用傳統方式實現jdbc操作

(2)使用反射實現jdbc的操作

(3)實現的步驟
第一步:建立註解,註解定義資料庫操作資訊的屬性
第二步:得到類的Class,得到帶註解的方法
    = Method getMethod(String name, Class<?>... parameterTypes) 
    == 第一個引數方法名稱,第二個引數方法裡面引數列表
第三步:得到方法上面的註解
    = <T extends Annotation> T  getAnnotation(Class<T> annotationClass)  
第四步:得到註解裡面的屬性的值

= 自定義的註解,在預設情況下作用範圍是原始碼階段,使用元註解設定的作用範圍

(4)核心的程式碼
    //得到Class
    Class clazz = TestJDBC02.class;
    //得到方法
    Method method = clazz.getMethod("testSelect");

    //得到方法上面的註解
    JdbcInfo info = method.getAnnotation(JdbcInfo.class);
    //得到註解裡面的屬性的值
    String drivername = info.drivername();
    String url = info.url();
    String username = info.username();
    String password = info.password();

相關推薦

檔案核心API的使用檔案下載註解(jdk註解定義註解)

第一部分:檔案的上傳 1、什麼是檔案的上傳 1.1 把本地的檔案儲存到伺服器上,這個過程稱為檔案的上傳。比如,網盤、qq空間 1.2 實現檔案的上傳 (1)jspSmartUpload:應用在jsp的模型一 = 適於嵌入執行上傳下載操作的JSP檔案

檔案的動作不能太俗必須頁面無重新整理

常規操作上傳檔案 1 <form action="xxx.action" method="post" enctype="multipart/form-data"> 2 <input type="file" name="userfile" multiple><br&

解決美化後的檔案控制元件(type=file)IE和firefox不相容的問題

        普通的file控制元件,在IE和firefox的表現會有所不同,為了美化上傳控制元件,通常會做一個text+button來替代file控制元件。 設定file控制元件完全透明,這樣在點選button的時候,其實就是點選隱藏的file控制元件的瀏覽,本來應該完

springmvc Excel檔案,使用ajaxSubmit方法進行檔案,使用彈出層彈出一個框(jquery layer)點選進行下載

效果: 彈出層使用的是jquery外掛layer  外掛下載地址http://download.csdn.net/detail/rendeyishi/8048139 因為我是使用的是jquery裡面的ajaxSubmit進行檔案上傳 所以這個jquery.form.js必

webuploader限制檔案型別 為一類的檔案檔案字尾不確定

例如 prt檔案,需要上傳的型別支援(prt1,prt11,prt.11,prt.44,prt.....) 配置中設定:    accept: {         title:'' 

檔案-阿里雲OSS-儲存檔案

JS上傳檔案到阿里雲OSS OSS支援流式寫入和讀出。特別適合視訊等大檔案的邊寫邊讀業務場景。 注意在OSS的控制檯:跨域管理中設定允許的方法 <script> var client = new OSS

檔案到資料庫 和 從資料庫下載檔案到本地

有時候我們需要把圖片、文件、dll檔案、等等,上傳的資料庫,然後當需要的時候再從資料庫中讀取到本地,下面我以上傳圖片為例,講解一下如何把本地的一張圖片上傳到資料庫,然後再從資料庫下載到本地。   工具:VS2010,Sql Server 2000。語言:C#。   像

apache檔案元件+oracle+SWFupload實現檔案

  來韓國三個月了,最近做的專案中韓國人要求上傳的檔案儲存到資料庫,讓人難以接受的是在上傳選擇檔案的時候他們要求能夠同時實現多檔案選擇並上傳,多選這個問題我以前沒做過,google一下,發現有很多辦法,最終發現了SWFupload元件,於是問題解決,現貼出程式碼以供以後備用和

Struts2檔案無法取得檔名及檔案型別問題的解決

     最近寫一網站,用struts2加Common-FileUpload實現照片上傳,在頁面表單裡寫成這樣:<s:file name="uploadPhoto"/>,然後在action中用以下三個屬性:     private File uploadPhoto

struts2檔案後找不到檔案檔案下載的問題

最近做一個關於檔案上傳下載的專案的時候,碰到幾個問題: 1.檔案上傳時<s:file name="upload" label="上傳論文" ></s:file>,此name屬性

檔案踩坑記及檔案清理原理探究

  最近搞一個檔案上傳功能,由於檔案太大,或者說其中包含了比較多的內容,需要大量邏輯處理。為了優化使用者體驗,自然想到使用非同步來做這件事。也就是說,使用者上傳完檔案後,我就開啟另一個執行緒來處理具體邏輯,主執行緒就直接返回使用者成功資訊了。這樣就顯得非常快了,要看具體結果可以到結果頁進行檢視。看起來很棒!

十三根據HDFS提供的API實現檔案下載刪除重新命名移動

一、 根據HDFS提供的API,實現以下功能: 針對檔案: 上傳、下載、刪除、重新命名、移動 package HdfsApi; import java.io.File; import java.io.FileInputStream; import java.io.IOExc

ASP.NET Core WEB API 使用element-ui檔案元件el-upload執行手動檔案檔案並在檔案後清空檔案

前言:   從開始學習Vue到使用element-ui-admin已經有將近快兩年的時間了,在之前的開發中使用element-ui上傳元件el-upload都是直接使用檔案選取後立即選擇上傳,今天剛好做了一個和之前類似的檔案選擇上傳的需求,不過這次是需要手動點選按鈕把檔案上傳到伺服器中進行資料匯入,而且最多隻

springMVC檔案MultipartHttpServletRequestMultipartFile進行檔案

這裡使用apache的開源jar包完成上傳功能,使用jar包分別是:common-fileupload.jar和common-io.jar  先編寫上傳檔案幫助類,如果需要區分檔案型別,可以將檔案字尾擷取進行判斷; springmvc-mvc.xml配置,這裡主要配置spri

檔案下載在form表單中設定屬性enctype=“multipart/form-data”的情況下如何獲取表單提交的值?

一、問題描述 檔案上傳下載時,在form表單中設定屬性enctype=“multipart/form-data”的情況下,如何獲取表單提交的有關使用者資訊的值?(比如:textfield、radio等屬性中的值) 二、解決方法 1、情況一:沒有對user物件進行封裝 方法:

Bootstrap fileinput.js最好用的檔案元件

本篇介紹如何使用bootstrap fileinput.js(最好用的檔案上傳元件)來進行圖片的展示,上傳,包括springMVC後端檔案儲存。 一、demo 二、外掛引入 <link type="text/css" rel="stylesheet" h

linux壓縮和解壓縮命令stp本地檔案下載和ssh連線與傳輸

linux 上檔案解壓縮指令 tar命令   解包:tar zxvf FileName.tar   打包:tar czvf FileName.tar DirName      解壓:tar zxvf FileName.tar.gz   壓縮:tar zcvf FileName.

webupload外掛中單個檔案處理

上傳外掛如何使用,我這裡就不多說了,網上大把教程。今天我要講的是如何限制上傳一個檔案,以及當檔案選擇錯誤是,再重新選擇檔案導致的問題。 預設給上傳外掛支援多檔案上傳,但是我們有很多需求是之上傳單個檔案,下面就來一起學習學習吧! 外掛html <div class="form-g

django FileField檔案重新命名ModelForm驗證儲存

models.py class TeleplayTable(models.Model): tid = models.CharField(max_length=50, primary_key=True, verbose_name='ID') name = models.Ch

檔案到本地磁碟磁碟路徑適應window和linux

private void uploadDisk(InputStream inputStream, String fileName) {         OutputStream os = null;     &