J2EE项目中经常会用到“文件上传”这个模块,虽然说很简单很同意,但不注意里面的一些小细节的话,也会让你抓破头皮想个几个小时。今天我就把刚刚完成的这个“文件上传”模块的过程和体会给写下来分享下。

 

此处我使用的是struts2的文件上传功能,它功能够强大了,适用大多数的项目。

 

主要需要做的有以下几步:

(1)文件上传前台jsp页面,上传成功jsp页面的编写。

(2)action类的中域的添加和上传方法的编写

(3)struts.xml的配置

 

文件上传前台代码如下:

 

  1. <form style="width: 100%" action="XXX" method="post" enctype="multipart/form-data"> 
  2.                             <table class="data_collection"> 
  3.                                 <tbody> 
  4.                                     <tr> 
  5.                                      
  6.                                         <td class="property_value"><input type="file" name="srcFile" /></td> 
  7.                                     </tr> 
  8.                                 </tbody> 
  9.                             </table> 
  10.                             <br/> 
  11.                             <table class="data_collection"> 
  12.                                 <thead> 
  13.                                     <tr><td class="title"><button type="submit" value="Submit">导入</button> 
  14.                                 </thead> 
  15.                             </table> 
  16.                         </form> 

 

它的显示效果如下:

 

代码中需要注意的是form中的属性enctype必须为multipart/form-data,以及<input type="file"/>中的name属性要和action中的“源文件”域的名称一致。

 

action中需要增加3个字段如下:

 

  1. private File srcFile;                                   // 源文件 
  2.     private String srcFileContentType;                              // 上传文件mime类型 
  3.     private String srcFileFileName;                             // 源文件名 

此处是最需要注意的地方,下面两个域的名称必须根据“源文件”的变量名来命名,即红色部分需要一致,否则就无法拿到上传文件的名称和类型。

整个action代码如下,各个方法都有注释:

 

  1. package cn.crh.maintenance.action; 
  2.  
  3. import java.io.BufferedInputStream; 
  4. import java.io.BufferedOutputStream; 
  5. import java.io.File; 
  6. import java.io.FileInputStream; 
  7. import java.io.FileOutputStream; 
  8. import java.io.InputStream; 
  9. import java.io.OutputStream; 
  10. import java.util.Date; 
  11.  
  12. import org.apache.struts2.ServletActionContext; 
  13.  
  14. import com.opensymphony.xwork2.ActionSupport; 
  15.  
  16. public class fileUploadAction extends ActionSupport { 
  17.  
  18.     public static final int BUFFER_SIZE = 16 * 1024;        // 每次读取文件的大小 
  19.      
  20.     private File srcFile;                                   // 源文件 
  21.     private String srcFileContentType;                              // 上传文件mime类型 
  22.     private String srcFileFileName;                             // 源文件名 
  23.     private String serverFileName;                          // 服务器上的文件名 
  24.      
  25.      
  26.     // 文件拷贝 
  27.     private static void copy(File src, File dst) { 
  28.         try { 
  29.             InputStream in = null
  30.             OutputStream out = null
  31.             try { 
  32.                 in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE); 
  33.                 out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE); 
  34.                 byte[] buffer = new byte[BUFFER_SIZE]; 
  35.                 while(in.read(buffer) > 0) { // 读 
  36.                     out.write(buffer);       // 写 
  37.                 } 
  38.                 System.out.println(src.getPath() + src.getName()); 
  39.             } finally { 
  40.                 if (in != null
  41.                     in.close(); 
  42.                 if (out != null
  43.                     out.close(); 
  44.             } 
  45.         } catch(Exception e) { 
  46.             e.printStackTrace(); 
  47.         } 
  48.     } 
  49.      
  50.     // 得到文件扩展名 
  51.     private String getExtention(String fileName) { 
  52.         int pos = fileName.lastIndexOf("."); 
  53.         return fileName.substring(pos); 
  54.     } 
  55.      
  56.     // 将用户上传的本地文件拷贝到服务器的一个目录下 
  57.     public String uploadFile() { 
  58.         //System.out.println("文件名是:" + this.srcFile.getName()); 
  59.         this.serverFileName = new Date().getTime() + this.getExtention(this.srcFileFileName); 
  60.         File serverFile = new File(ServletActionContext.getServletContext().getRealPath("/tempFiles") + "/" + this.serverFileName); 
  61.         this.copy(this.srcFile, serverFile); 
  62.         return SUCCESS; 
  63.     } 
  64.  
  65.  
  66.  
  67.     public String getServerFileName() { 
  68.         return serverFileName; 
  69.     } 
  70.  
  71.     public void setServerFileName(String serverFileName) { 
  72.         this.serverFileName = serverFileName; 
  73.     } 
  74.  
  75.     public File getSrcFile() { 
  76.         return srcFile; 
  77.     } 
  78.  
  79.     public void setSrcFile(File srcFile) { 
  80.         this.srcFile = srcFile; 
  81.     } 
  82.  
  83.  
  84.     public String getSrcFileContentType() { 
  85.         return srcFileContentType; 
  86.     } 
  87.  
  88.     public void setSrcFileContentType(String srcFileContentType) { 
  89.         this.srcFileContentType = srcFileContentType; 
  90.     } 
  91.  
  92.     public String getSrcFileFileName() { 
  93.         return srcFileFileName; 
  94.     } 
  95.  
  96.     public void setSrcFileFileName(String srcFileFileName) { 
  97.         this.srcFileFileName = srcFileFileName; 
  98.     } 
  99.      

最后是struts.xml的配置,关键代码如下:

 

  1. <action name="uploadRoutingInfoFile" class="fileUploadAction" method="uploadFile"> 
  2.             <interceptor-ref name="fileUpload"> 
  3.             </interceptor-ref> 
  4.             <interceptor-ref name="defaultStack"></interceptor-ref> 
  5.             <result name="success">/jsp/trainMovementInfo/showUploadSuccess.jsp</result> 
  6.         </action> 

需要注意的是不要忘记添加struts2的文件上传拦截器。

 

如果运行的时候有问题,可能原因有:

(1)找不到struts2的临时文件目录。

解决方法:在struts.xml中添加如下语句:

 

  1. <constant name="struts.multipart.saveDir" value="/temp"></constant> 

(2)文件太大导致上传失败

解决方法:在拦截器中配置允许上传文件大小的param。