熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

通用上載組件的原理及實現

2013-11-15 11:48:33  來源: JSP教程 

  JSP/SERVLET上載的難點
  支持任意格式任意數量的文件上載上載控制的實現表單信息的取得即插即用的應用方法我個人認為制約通用 上載組件的實現主要是這四個難點
  
  JSP/SERVLET上傳的原理
  JSP/SERVLET文件 上載是通過ServletInputStream類來實現的ServletInputStream類是javaioInputStream的一個擴展抽象類實質上也是一個輸入流通過ReadLine方法從Request端一行一行讀取可見JSP/SERVLET上載根本上是用流來實現的理解了這個就不難理解整個 上載的原理ServletInputStream實現文件 上載必須采用HTTP POST或者HTTP PUT協議HTTP GET協議只能傳遞很少的數據是不能實現文件上載的
  
  下面我們來看一下上傳的數據流的結構首先要在BROWSER端給出一個請求我們的請求如下(文件名為testjsp):
  <%@ page contentType=text/html; charset=GBK %>
  <html>
  <head>
  
  <title>文件上載</title>
  </head>
  <body>
  <form action=testjsp enctype=MULTIPART/FORMDATA method=post>
  說明一: <input type=text name=explain />
  <br />
  說明二: <input type=text name=explain />
  <br />
  請選擇上載文件 <input type=file name=file />
  <br />
  請選擇上載文件 <input type=file name=file />
  <br />
  說明三: <input type=text name=explain />
  <br />
  <input type=submit value= 上 載 />
  </form>
  </body>
  </html>
  顯示如下
  
  說明一
  
  說明二
  
  請選擇上載文件一
  
  請選擇上載文件二
  
  說明三
  
  在上載請求頁中混雜了表單的三個輸入框及兩個上載文件當然輸入框可以更多更雜可以有選擇框單選及多選按鈕待上傳的文件也可以有三個四個或所需要的更多
  
  action=testjsp表示表單將提交到testjsp另外注意表單屬性中必須要有這句enctype=MULTIPART/FORMDATAenctype指定 Form 輸入資料的編碼方式method屬性必須為post這樣表單才能提交大量數據也表示本表單的數據傳遞將用流操作method=get表示數據將通過地址欄進行傳遞雖然方便快捷但只適合很少的數據量
  
  響應端testjsp頁面如下
  
  <%@ page contentType=text/html; charset=GBK %>
  <html>
  <head>
  <title>文件上載</title>
  </head>
  <body>
  <jsp:useBean id=upBean scope=page class=comuploadUpBean/>
  <%
  upBeandoUpload(request);
  outprintln(上載已完成請查看輸出文件);
  %>
  </body>
  </html>
  
  testjsp收到請求後調用一個java bean執行doUpload(request)操作本操作將完成流(unicode格式)的接收並不做任何處理地將流順序寫入一個文本文件裡讀寫操作中用了一個緩沖區byte[] readByte用了一個ServletInputStream 的一個方法readLine(byte[] b int offint len)方法讀取流請大家注意ServletInputStream 流的read Line方法是一次讀入指定大小的行java bean (UpBeanjava)代碼如下
  
  [code]package comupload;
  
  import javaio*;
  import javaxservlet*;
  import javaxservlethttpHttpServletRequest;
  import javaxservletServletInputStream;
  
  public class UpBean {
  
  public void doUpload(HttpServletRequest req) throws ServletException IOExcept
  ion{
  //首先定義一個文本文件
  File file = new File(outtxt);
  //readCount 記錄從輸入流中實際讀取的字符數
  int readCount;
  //輸入流緩沖區
  byte[] readByte = new byte[];
  //初始化輸入流
  ServletInputStream servletInputStream = reqgetInputStream();
  //初始化一個輸出流(到文件)
  FileOutputStream fileOutputStream = new FileOutputStream(file);
  //循環從讀取輸入流中讀取字節
  readCount = servletInputStreamreadLine(readByte readBytelength);
  
  while(readCount != ){
  fileOutputStreamwrite(readBytereadCount);
  readCount = servletInputStreamreadLine(readByte );
  }
  //關閉文件流
  fileOutputStreamflush();
  }
  }[/code]
  
  為了便於我們閱讀流上載的兩個文件為兩個簡單的文本文件(有格式的文件不便於直接分析)onetxt及twotxt文件內容如下實驗時請建立對應文本文件內容請直接copy以下所示
  
  onetxt:
  
  one
  one one
  one one one
  
     twotxt
  two
  two two
  two two two
  
  都准備好以後我們就可以運行了運行時請注意文本部分及文件部分最好不要出現漢字或其他雙字符集字符盡量采用英文因為接收是采用的Unicode字符集我們未對輸入做任何處理 我們在三個輸入框輸入的字符為說明一explain說明二explain說明三explainouttxt接收到如下字符
  
  dae
  ContentDisposition: formdata; name=explain
  
  explain
  dae
  ContentDisposition: formdata; name=explain
  
  explain
  dae
  ContentDisposition: formdata; name=file; filename=C:\test\onetxt
  ContentType: text/plain
  
  one
  
  one one
  one one one
  dae
  ContentDisposition: formdata; name=file; filename=C:\test\twotxt
  ContentType: text/plain
  
  two
  two two
  two two two
  dae
  ContentDisposition: formdata; name=explain
  
  explain
  dae
  可以很明顯的看到outtxt被dae分成了五 節即表單的每個輸入部分都對應一節結尾部分是dae剛好比開始的一段字符在最後多出兩個 每節的第一行是輸入內容的說明ContentDisposition: formdataname=explain表示 上載請求項的name文本輸入部分僅這兩個說明如果輸入的是文件還用兩項說明filename=C:\test\onetxt表示輸入源基於mswindows的ie上載帶有完整的路徑netscape及其他浏覽器可能只有一個文件名還有一項是關於輸入格式的ContentType:text/plain表示輸入格式是文本類型如果我們上載的是bmp文件則為ContentType: image/bmpword文件為application/msword說明的下面緊接著是一個空行然後下面才是我們所需的內容
  
  仔細分析未加修改的輸入流格式有助於我們實現文件與輸入文本的准確分離
  通過以上的分析可以看出准確分離上載的文件及文本信息需要以下要素數據段分割符結束符(比分割符多出兩個輸入文本及上載的文件區分標志(文本為name=文件為filename=編碼格式可以通過HttpServletRequest 類getCharacterEncoding() 方法取得表單文本部分名稱及內容名稱為name=後面的字符內容為該段第三行及以後的內容文件名稱及內容名稱為filename=後面的字符內容為該段第三行及以後的內容
  
  下面我們將討論輸入流的分離
  
  程序實現分析
  我們首先畫出程序實現的主體結構圖請注意判斷文件標志(indexOf(filename=)>)與判斷文本標志(indexOf(name=)>)的順序當(indexOf(filename=)>)成立時(indexOf(name=)>)一定也是成立的所以判斷文件要在判斷文本前
  
  分離文件及輸入文本為完整保存上載的文件信息及輸入的文本信息本程序建立了兩個類public class FileInfo public class InputField及兩個線性表private ArrayList upFilesListprivate ArrayList inputFieldList用於動態增加文件信息及文本信息定義如下
  
  FileInfojava(記錄上載文件信息)
  
  package comupload;
  
  public class FileInfo {
  private String fileName;
  private boolean validFlag;
  private String filePath;
  private long fileSize;
  
  //設置文件信息
  //上載文件是否有效標志
  public void setValidFlag(boolean validFlag){
  
  thisvalidFlag = validFlag;
  }
  //文件名
  public void setFileName(String filename){
  thisfileName = filename;
  }
  //存貯路徑
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19662.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.