upload文件的上傳

在Servlet中,upload上傳是我們常用的操作之一。然而在javax.servlet包中,javax.servlet.http.Htt ervletRequest對於form中的enctype
  ="multipart/form-data"的內容的處理支持卻極有限,我們不得不手工編寫讀取和分離Stream中的內容的代碼。這使我們對封裝完好的MultipartFormDataRequest提供支持的包充滿了期待。其實常用的javaZoom的uploadBean中,就已經提供了這個良好的工具。另外,uploadBean還包括了上傳後的存儲機制,如保存到數據庫、文件、zip文件等。如果你不需要做定製的話,儘管可以使用他們。當然定製上傳後的處理很簡單也很實用。
  javaZoom的包中共包含了7個cla 文件:
  UploadBean.cla
  
  UploadParameters.cla
  
  UploadListener.cla
  
  UploadFile.cla
  
  UploadException.cla
  
  Archiver.cla
  
  MultipartFormDataRequest.cla
  
  其中,我們最感興趣的是MultipartFormDataRequest.cla 。正如其名,它使我們可以象處理一般的form那樣處理enctype="multipart/form-data"的form的內容。
  
  在MutipartFormDataRequest中,共有5種public方法:
  
  getParameterNames(name:String):Enumeration
  
  getParameterValue(name:String):String
  
  getParameterValues(name:String):String[]
  
  getFiles():Hashtable
  
  isMultipartFormData(req:Htt ervletRequest):boolean
  
  和2種public構造函數:
  
  MultipartFormDataRequest(req:Htt ervletRequest,maxcontentlength:int)
  
  MultipartFormDataRequest(req:Htt ervletRequest)
  
  所有的對Mutipart的內容的分析,在構造函數中由 com.oreilly.servlet.multipart包中的分析器完成。我們無需關心原先最頭疼的對Stream內容的分析的工作,只需要象下面的代碼那樣:
  
  if (MultipartFormDataRequest.isMultipartFormData(request)){//如果是multipart類型的request
  
  MultipartFormDataRequest mrequest = new MultipartFormDataRequest(request);
  
  }
  
  就得到了MutipartFormDataRequest的實例。
  
  如果想得到上傳的內容:
  
  Hashtable files = mrequest.getFiles();//得到所有的上傳的文件
  
  if(files!=null !files.isEmpty()){
  
  UploadFile file=(UploadFile)files.get(name);// name:String 文件輸入框的名稱
  
  // file:UploadFile 文件
  
  }
  
  在這裏,UploadFile file中包含了我們感興趣的上傳的文件的所有的信息:
  
  getData():byte[] 文件的內容
  
  getFileSize():long 文件的長度
  
  getContentType():String 文件的編碼
  
  getFileName():String 文件的名稱
  
  
  這些信息足夠我們進行一般所想要的操作了。
  
  正如uploadBean的名稱所言,uploadBean提供對某些常用上傳操作的封裝。
  
  在uploadBean中,setStoreModel(storeModel:int)提供了對上傳文件以下幾種形式的保存
  
  0 保存在內存中
  
  1 保存在指定目錄中
  
  2 保存在數據庫中
  
  3 保存在zip文件中
  
  4 保存在Tagzip文件中
  
  5 序列化形式保存
  
  6 Xml形式保存
  
  不過以上每一種形式的保存,都需要符合uploadBean中所指的一些規則。如保存在數據庫中,uploadBean是把數據庫純粹作爲一種存儲手段,關鍵字都是用TimeStamp生成的;保存在目錄中,不能指定3層以上目錄。
  
  如我們需要把上傳文件用自己的方式保存,可以採用重新編寫保存或者直接重載uploadBean實現。
  
  從byte[]data=file.getData();中,我們得到文件的字節數組;很容易通過構造新的流,進行文件的輸入輸出,存儲到數據庫,保存在各種形式的載體中。
  
  
  實例1:上傳文件並且存放到數據庫中
  
  數據庫表格:TestTable
  
  lsh char(10) pk,
  
  nr clob(1000000)
  
  
  //數據庫基本操作
  
  package upload.example1;
  
  import java.sql.*;
  
  import javax.sq1.*;
  
  import javax.naming.*;
  
  public cla DbO (){
  
  private DataSource d
  
  private Co ection co
  
  private String env="java:comp/env/jdbc/TestDB";
  public String getEnv(){return env;}
  public void setEnv(String env){this.env=env;}
  public DataSource getDataSource(){//取得數據源(連結池)
  try{
  
  Context ictx=new InitalContext();
  
  ds=(DataSource)ictx.lookup(env);
  
  }catch(Exception ignore){
  
  //some debug codes
  
  }
  return d
  }
  public Co ection getCo ection(){//取得數據庫連結
  if(ds==null)ds=getDataSource();
  
  try{
  
  if(co ==null)co =ds.getCo ection();
  
  }catch(Exception ignore){
  
  //some debug codes
  
  }
  return co
  }
  }
  //存儲
  package upload.example1;
  
  import java.sql.*;
  
  public cla D tore(){
  
  public static String ISFILEEXIST="select count(*) from TestTable where lsh=?";
  
  public static String I ERTFILE="i ert into TestTable (lsh)values(?)";
  
  public static String UPDATEFILE="update TestTable set nr=? where lsh=?";
  
  Co ection co
  
  DbO dbo
  
  protected boolean isFileExist(String lsh)throws SQLException{
  
  PreparedStatement t=co .prepareStatement(ISFILEEXIST);
  
   t.setString(1,lsh);
  
  ResultSet rs= t.executeQuery();
  
  int count;
  
  for(count=0;rs.next();count=rs.getInt(1));
  
   t.close();
  
  if(count<=0)return false;
  
  else return true;
  
  }
  
  protected void i ertFile(String lsh)throws SQLException{
  
  PreparedStatement t=co .prepareStatement(I ERTFILE);
  
   t.setString(1,lsh);
  
   t.executeUpdate();
  
   t.close();
  
  }
  
  protected void updateFile(String lsh,byte[]data)throws SQLException{
  
  PreparedStatement t=co .prepareStatement(UPDATEFILE);
  
   t.setBytes(1,data);
  
   t.setString(2,lsh);
  
   t.executeUpdate();
  
   t.close();
  
  }
  
  public void saveFile(String lsh,byte[]data)throws SQLException{
  
  if(lsh==null || data==null ||lsh.trim().length()==0)retur
  
  
  if(dbo ==null)dbo =new DbO ();
  
  if(co ==null)co =dbo .getCo ection();
  
  
  if(!isFileExist(lsh)){
  
  i ertFile(lsh);
  
  }
  
  updateFile(lsh,data);
  
  
  co .close();
  
  co =null;
  
  }
  
  }
  
  //servlet 片斷(servlet 中應包含javazoom.upload.*;java.util.*;)
  
  D tore d =new D tore();
  
  if (MultipartFormDataRequest.isMultipartFormData(request))
  
  {
  
  MultipartFormDataRequest mrequest = new MultipartFormDataRequest(request);
  
  if(mrequest.getParameter("submit")!=null){
  
  String lsh=mrequest.getParameter("lsh");
  
  Hashtable files = mrequest.getFiles();
  
  UploadFile file = files.get("ufile");
  
  byte[]data=file.getData();
  
  try{
  
  d .saveFile(lsh,data);
  
  }catch(Exception e){
  
  //debugCodes
  
  }
  }
  }
  //Submit html 片斷
  
  

  

  

  

  實際運行以上代碼時,注意DbO 的env參數需要和實際的服務器配置的連結池參數一致,並且需要有upload.jar 和 cos.jar這兩個包。如果是在We hpere 4上,請把他們拷貝到項目的webA lication/WEB-INF/lib下。如果是Resin上,把他們拷貝到項目的WEB-INF/lib下。
  
  
  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章