学习Struts--Chap07:Struts2文件上传和下载
1、struts2文件上传
1.1、struts2文件上传的基本概述
在开发web应用的时候,我们一般会为用户提供文件上传的功能,比如用户上传一张图像作为头像等。为了能上传文件,我们必须将表单的method设置为POST,将enctype设置为multipart/form-data
。只有在这种情况下,浏览器才会把用户选择文件的二进制数据发送给服务器。Struts2并未提供自己的请求解析器,也就是说,Struts2不会自己去处理multipart/form-data的请求,它需要调用其它上传框架来解析二进制请求数据,但Struts2在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
1.2、struts2文件上传的一些规范说明
- Struts2 文件上传基于 Struts2 拦截器实现;
- Struts2 文件上传使用的是 fileupload 组件;
- Form表单中需要配置 enctype="multipart/form-data";以便于让文件以二进制的形式传送给服务器。
- Struts2 获取上传文件:name (name 是文件表单的 name);
- Struts2 获取上传文件名:name+FileName;
- Struts2 获取上传文件的类型:name+ContentType;
1.3、struts2文件上传的代码实例
上传文件的首页:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="s" uri="/struts-tags" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>上传文件的首页</title> 9 </head> 10 <body> 11 <!-- 因为我们对文件的类型和文件的大小进行了限制,所以当出现不符合要求的文件上传的情况发生的时候,系统会报错用以提示用户 --> 12 <s:fielderror></s:fielderror> 13 <form action="upload" method="post" enctype="multipart/form-data"> 14 文件:<input type="file" name="java1234"/><br/> 15 <input type="submit" value="提交"/> 16 </form> 17 </body> 18 </html>
用于处理上传文件的Action:
1 package com.java1234.action; 2 3 import java.io.File; 4 5 import org.apache.commons.io.FileUtils; 6 7 import com.opensymphony.xwork2.ActionSupport; 8 9 public class FileUploadAction extends ActionSupport{ 10 11 private static final long serialVersionUID = 1L; 12 13 private File java1234; // �ļ�应以一个文件,一定要和form表单中的文件名称一致 14 15 private String java1234FileName; //定义一个变量表示文件名称(这个名称是有规范说明的) 16 17 private String java1234ContentType; //定义一个变量表示文件类型(这个名称是有规范说明的) 18 19 public File getJava1234() { 20 return java1234; 21 } 22 23 public void setJava1234(File java1234) { 24 this.java1234 = java1234; 25 } 26 27 public String getJava1234FileName() { 28 return java1234FileName; 29 } 30 31 public void setJava1234FileName(String java1234FileName) { 32 this.java1234FileName = java1234FileName; 33 } 34 35 public String getJava1234ContentType() { 36 return java1234ContentType; 37 } 38 39 public void setJava1234ContentType(String java1234ContentType) { 40 this.java1234ContentType = java1234ContentType; 41 } 42 43 @Override 44 public String execute() throws Exception { 45 System.out.println("文件名称"+java1234FileName); 46 System.out.println("文件类型"+java1234ContentType); 47 String filePath="C:/"+java1234FileName; 48 File saveFile=new File(filePath); 49 FileUtils.copyFile(java1234, saveFile); 50 return SUCCESS; 51 } 52 53 54 55 56 }
Struts2.xml文件的配置:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4 "http://struts.apache.org/dtds/struts-2.0.dtd"> 5 6 <struts> 7 <!-- 允许上传大文件 --> 8 <constant name="struts.multipart.maxSize" value="20000000"></constant> 9 10 <package name="manager" extends="struts-default"> 11 12 <action name="upload" class="com.java1234.action.FileUploadAction"> 13 <result name="success">/success.jsp</result> 14 <result name="input">/fileupload.jsp</result> 15 16 <!-- 配置文件的大小及类型 --> 17 <interceptor-ref name="fileUpload"> 18 <param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param> 19 <param name="maximumSize">81101</param> 20 </interceptor-ref> 21 22 <!-- 特别注意:当我们重写一个拦截器的时候,根据规范要求就不会再使用默认的拦截器, 23 所以我们要想继续使用默认的拦截器,就需要在这个重新引用一下 --> 24 <interceptor-ref name="defaultStack"></interceptor-ref> 25 </action> 26 27 </package> 28 29 </struts>
文件上传成功之后的返回页:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="s" uri="/struts-tags" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>上传成功之后的返回页</title> 9 </head> 10 <body> 11 文件上传成功! 12 </body> 13 </html>
2、配置上传文件的类型和大小
1 <param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param> 2 <param name="maximumSize">81101</param>
我们需要在struts.xml文件中对应的<action>标签中配置上传文件的类型和大小,因为我们知道struts2的文件上传功能是基于拦截器实现的,为了实现这个限制上传文件大小和类型的功能,我们需要在一个
名为:fileUpload的拦截器中添加参数,参数的类型以及写法如上代码所展示的。当我们重写一个拦截器的时候,根据规范要求就不会再使用默认的拦截器,所以我们要想继续使用默认的拦截器,就需要在这里
重新引用一下defaultStack。
3、如何实现大文件的上传
<constant name="struts.multipart.maxSize" value="20000000"></constant>
要想实现文件上传只需要在配置文件的的<package>标签的外边添加上如上的代码,意思就是重新定义一下允许上传的最大文件为多少。
4、如何实现多文件上传
其实,实现多文件的上传和单个文件上传的基本思路是一样的,不同的地方就是如果我们要想一次性上传多个文件,首先就是上传的界面端要允许一次性选择多个文件,然后就是对应处理请求的Action要使用数组的形式循环处理每一个上传的文件,但话又说回来了,单独看每一次循环的时候,就和单独上传一个文件时的处理是没有区别的。
我接下来会用代码简单演示如何实现多文件上传:
上传文件的首页:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="s" uri="/struts-tags" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 <s:fielderror></s:fielderror> 12 <form action="uploads" method="post" enctype="multipart/form-data"> 13 文件1:<input type="file" name="java1234"/><br/> 14 文件2:<input type="file" name="java1234"/><br/> 15 文件3:<input type="file" name="java1234"/><br/> 16 <input type="submit" value="提交"/> 17 </form> 18 </body> 19 </html>
用于处理上传文件的Action:
1 package com.java1234.action; 2 3 import java.io.File; 4 5 import org.apache.commons.io.FileUtils; 6 7 import com.opensymphony.xwork2.ActionSupport; 8 9 public class FilesUploadAction extends ActionSupport{ 10 11 /** 12 * 13 */ 14 private static final long serialVersionUID = 1L; 15 16 17 18 private File[] java1234; // 文件,使用数组进行接收 19 20 private String[] java1234FileName; // 文件名,使用数组进行接收 21 22 private String[] java1234ContentType; // 文件类型,使用数组进行接收 23 24 25 26 public File[] getJava1234() { 27 return java1234; 28 } 29 30 31 32 public void setJava1234(File[] java1234) { 33 this.java1234 = java1234; 34 } 35 36 37 38 public String[] getJava1234FileName() { 39 return java1234FileName; 40 } 41 42 43 44 public void setJava1234FileName(String[] java1234FileName) { 45 this.java1234FileName = java1234FileName; 46 } 47 48 49 50 public String[] getJava1234ContentType() { 51 return java1234ContentType; 52 } 53 54 55 56 public void setJava1234ContentType(String[] java1234ContentType) { 57 this.java1234ContentType = java1234ContentType; 58 } 59 60 61 62 @Override 63 public String execute() throws Exception { 64 //循环处理每一个接收到的文件,其实每一次遍历循环就相当于是处理一个单个上传的文件 65 for(int i=0;i<java1234.length;i++){ 66 System.out.println("文件名:"+java1234FileName[i]); 67 System.out.println("文件类型:"+java1234ContentType[i]); 68 String filePath="C:/"+java1234FileName[i]; 69 File saveFile=new File(filePath); 70 FileUtils.copyFile(java1234[i], saveFile); 71 } 72 return SUCCESS; 73 } 74 75 76 77 78 }
Struts2.xml文件的配置:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4 "http://struts.apache.org/dtds/struts-2.0.dtd"> 5 6 <struts> 7 8 <constant name="struts.multipart.maxSize" value="20000000"></constant> 9 10 <package name="manager" extends="struts-default"> 11 12 <action name="uploads" class="com.java1234.action.FilesUploadAction"> 13 <result name="success">/success.jsp</result> 14 <result name="input">/filesupload.jsp</result> 15 </action> 16 17 </package> 18 19 </struts>
文件上传成功之后的返回页:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="s" uri="/struts-tags" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 全部文件上传成功! 12 </body> 13 </html>
5、struts2文件下载
文件下载就是在指定的地地方把指定的文件下载到指定的地方的一个过程,这里边最需要注意的是文件下载是以二进制流(InputStream)的形式进行传输的,所以我们要注意在获取文件名称的时候使用格式的转化,防止出现乱码的现象;还有一个就是文件地址的设置问题,这些细节地方不注意的话都会引起代码的运行错误。为了简单起见,我们可以指定下载的链接地址,然后通过代码处理来设定下载后的文件名称是什么。
Action.java文件:
1 package com.java1234.action; 2 3 import java.io.InputStream; 4 5 import org.apache.struts2.ServletActionContext; 6 7 import com.opensymphony.xwork2.ActionSupport; 8 9 public class FileDownLoadAction extends ActionSupport { 10 11 /** 12 * 13 */ 14 private static final long serialVersionUID = 1L; 15 16 private String downloadPath;// 文件下载的路径 17 private String contentType;// 下载的文件类型 18 private String fileName;// 下载的文件名称 19 20 public String getDownloadPath() { 21 return downloadPath; 22 } 23 24 public void setDownloadPath(String downloadPath) { 25 this.downloadPath = downloadPath; 26 } 27 28 public String getContentType() { 29 return contentType; 30 } 31 32 public void setContentType(String contentType) { 33 this.contentType = contentType; 34 } 35 36 public String getFileName() { 37 return fileName; 38 } 39 40 public void setFileName(String fileName) { 41 this.fileName = fileName; 42 } 43 44 @Override 45 public String execute() throws Exception { 46 // 获取想要下载的文件的相对路径 47 downloadPath = ServletActionContext.getRequest().getParameter("download"); 48 // 借助lastIndexOf函数找到最后一个‘/’后边的字符串就是文件的名称 49 int position = downloadPath.lastIndexOf("/"); 50 // 为了安全起见。需要先进行一个判断 51 // 如果pasition的数值大于0.那么就说明这个文件名称前面还有一个相对路径 52 if (position > 0) { 53 // 获取文件名称 54 fileName = downloadPath.substring(position + 1); 55 } else { 56 fileName = downloadPath; 57 } 58 // 指定下载的文件的类型 59 contentType = "application/msword"; 60 return SUCCESS; 61 } 62 63 public InputStream getInputStream() throws Exception { 64 InputStream inputStream1 = ServletActionContext.getServletContext() 65 .getResourceAsStream(downloadPath); 66 return inputStream1; 67 } 68 }
struts2.xml文件:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4 "http://struts.apache.org/dtds/struts-2.0.dtd"> 5 6 <struts> 7 <package name="default" namespace="/" extends="struts-default"> 8 <action name="downloadFile" class="com.java1234.action.FileDownLoadAction"> 9 <!-- result类型是流(stream)类型 --> 10 <result name="success" type="stream"> 11 <!-- inputName指向被下载文件的来源,对应Action中返回的InputStream --> 12 <param name="inputName">inputStream1</param> 13 <!-- 下载的内容类型,如图片类型、文档类型等…… --> 14 <param name="contentType">${contentType}</param> 15 <param name="contentDisposition"> 16 <!-- 指定文件下载的处理方式,内联(inline)和附件(attachment)两种方式,attachment会弹出文件保存对话框 --> 17 attachment;filename=${filename} 18 </param> 19 </result> 20 </action> 21 </package> 22 </struts>
filedownload.jsp文件:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 7 <html> 8 <head> 9 <base href="<%=basePath%>"> 10 <title>FileDownLoad</title> 11 </head> 12 <body> 13 <a href="<%=Path%>/downloadFile?download=UploadFile/readme.doc">点击链接下载文件</a> 14 </body> 15 </html>