Struts2 实现单/多文件上传
通过struts2提供的fileUpload拦截器可以方便的实现文件的上传。那么我们来简单的实现以下:
首先,我们新建一个action
1 public class ToUploadAction extends ActionSupport { 2 3 private File fileUpload; 4 5 private String fileUploadFileName;//文件的名称 如上传的文件是a.png 则fileuploadFileName值为"a.png" 6 private String fileUploadContentType;//文件的类型 如上传的是png格式的图片,则fileuploadContentType值为"image/png" 7 /* 8 * 指定上传文件在服务器上的保存目录,需要在Action中为定义savePath变量并为其添加相应的setter和getter方法 9 * 便于Struts2将struts.xml中的<param name="savePath">uploads/</param>值赋给savePath属性 10 * <param>的作用就是为Action中的某些属性赋一个默认值,通常这样做的如配置路径、文件名之类的.... 传递参数 11 */ 12 private String savePath;//文件的保存位置 ,是在struts.xml中配置的 13 14 /** 15 * 16 */ 17 private static final long serialVersionUID = 8750193097637832895L; 18 19 public String fileUpload() throws IOException{ 20 21 String absolutePath = ServletActionContext.getServletContext().getRealPath(""); // 获取项目根路径 22 //文件路径 23 String path = absolutePath + "/" + this.savePath + "/"; 24 //创建路径,如果目录不存在,则创建 25 File file = new File(path); 26 if(!file.exists()) { 27 file.mkdirs(); 28 } 29 //文件路径+文件名 30 path +=this.getFileUploadFileName(); 31 //1.构建输入流 32 FileInputStream fis = new FileInputStream(fileUpload); 33 //2.构建输出流 34 FileOutputStream fos = new FileOutputStream(path); 35 //3.通过字节写入输出流 36 try { 37 byte[] buf = new byte[1024]; 38 int len = 0; 39 while ((len = fis.read(buf)) > 0) { 40 fos.write(buf, 0, len); 41 } 42 } catch (Exception e) { 43 e.printStackTrace(); 44 } finally { 45 fis.close(); 46 fos.close(); 47 } 48 return SUCCESS; 49 }
其中需要注意的就是,前面四个属性名称。fileUpload是通过表单传到后台的文件对象,fileUploadFileName是代表的上传文件的名称,属性名必须以前面文件对象的属性名fileUpload + FileName 来命名。否则一定无法接受到参数,不能获取文件名。同时fileUploadContentType也是同样的道理。savePath这个属性代表我们上传之后的存放地址的目录名。这个参数需要到struts.xml中进行配置,且需要命名一致。
当我们的控制层完成了之后就可以写我们的struts.xml配置文件。当然我们需要用到fileUpload这个拦截器:
1 <struts> 2 3 <constant name="struts.devMode" value="true" /> 4 <package name="fileUpload" extends="struts-default" namespace="/file"> 5 6 <action name="fileUpload" class="com.deppon.file.ToUploadAction" method="fileUpload"> 7 <interceptor-ref name="fileUpload"> 8 <param name="allowedTypes"> 9 image/bmp,image/png,image/gif,image/jpeg,image/jpg 10 </param> 11 <param name="maximumSize">1024*1024</param> 12 </interceptor-ref> 13 <interceptor-ref name="defaultStack" /> 14 <param name="savePath">uploads</param> 15 <result name="success">/success.jsp</result> 16 <result name="input">/fileUpload.jsp</result> 17 </action> 18 19 </package> 20 21 </struts>
我们必须也要加上struts默认的defaultStack这个拦截器,且要放在fileUpload拦截器的后面。这里的savePath参数配置的就是目录名,和action中的属性对应,这样action中 就可以取到我们配置的文件名。
最后来到了我们的展示层:
1 <s:form action="./file/fileUpload.action" method ="POST" enctype ="multipart/form-data"> 2 <s:file name ="fileUpload"/> 3 <s:submit value="上传" label="upload"/> 4 </s:form>
必须提供method 和 enctype这两个属性,且不能改变,这样才能上传文件格式。这样我们就基本实现了文件的上传功能。如果我们需要上传多个文件,只需要修改如下属性:
1 private List<File> image;//上传的文件 2 private List<String> imageFileName;//文件的名字 3 private List<String> imageContentType;//文件的类型
然后在方法中进行循环遍历,同时form表单的file元素的name属性一定要全部相同,这样struts2就会自动为我们进行处理。如下:
1 <s:file name="image" label="图片"></s:file> 2 3 <s:file name="image" label="图片"></s:file> 4 5 <s:file name="image" label="图片"></s:file>
循环遍历文件对象和文件名即可。
1 public String fileUpload() throws IOException{ 2 int i = 0; 3 for(File f : getFileUpload()){ 4 String absolutePath = ServletActionContext.getServletContext().getRealPath(""); // 获取项目根路径 5 //文件路径 6 String path = absolutePath + "/" + this.savePath + "/"; 7 //创建路径,如果目录不存在,则创建 8 File file = new File(path); 9 if(!file.exists()) { 10 file.mkdirs(); 11 } 12 //文件路径+文件名 13 path +=fileUploadFileName.get(i); 14 //1.构建输入流 15 FileInputStream fis = new FileInputStream(f); 16 //2.构建输出流 17 FileOutputStream fos = new FileOutputStream(path); 18 //3.通过字节写入输出流 19 try { 20 byte[] buf = new byte[1024]; 21 int len = 0; 22 while ((len = fis.read(buf)) > 0) { 23 fos.write(buf, 0, len); 24 } 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } finally { 28 fis.close(); 29 fos.close(); 30 } 31 i++; 32 } 33 return SUCCESS; 34 }