实现使用Struts2文件上传和文件下载:
注意点:
(1)对应表单的file1和私有成员变量的名称必须一致
<input type="file" name="file1"/>
private File file1;
(2)限制上传文件大小和类型的格式是定死的,最好记住,记不住知道去哪里查;虽然不做要求,完全懂框架内部的机制,但是找一些东西还是需要能找到的,这样你可以很好的实现一些功能,因为这些关键字都是框架底层定义好的,图一是找到配置上传文件大小的关键字,图二是找到设置文件类型的关键字。
1:第一步,引入核心包,省略;
2:在web.xml配置过滤器,如下所示:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> 3 <display-name>struts2_upload20170306</display-name> 4 <welcome-file-list> 5 <welcome-file>index.html</welcome-file> 6 <welcome-file>index.htm</welcome-file> 7 <welcome-file>index.jsp</welcome-file> 8 <welcome-file>default.html</welcome-file> 9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 13 <!-- 其他过滤器 --> 14 15 <!-- 引入struts2的核心过滤器 --> 16 <filter> 17 <!-- 过滤器的名称 --> 18 <filter-name>struts2</filter-name> 19 <!-- 过滤器类 --> 20 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 21 </filter> 22 <filter-mapping> 23 <!-- 过滤器名称 --> 24 <filter-name>struts2</filter-name> 25 <!-- 过滤器映射 --> 26 <url-pattern>/*</url-pattern> 27 </filter-mapping> 28 29 </web-app>
3:创建上传文件的页面uploadfile.jsp,源码如下所示:
需要注意form标签需要引入这句:enctype="multipart/form-data"
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>上传文件的页面</title> 8 </head> 9 <body> 10 11 <form action="${pageContext.request.contextPath }/fileUploadAction" method="post" enctype="multipart/form-data"> 12 文件名:<input type="text" name="filename"/><br/> 13 文件:<input type="file" name="file1"/><br/> 14 <input type="submit" value="上传文件"> 15 </form> 16 </body> 17 </html>
4:开发action,实现对文件上传后台的处理:已经加了详细的注释,需要注意的地方都加了注释;
1 package com.bie.upload; 2 3 import java.io.File; 4 5 import org.apache.commons.io.FileUtils; 6 import org.apache.struts2.ServletActionContext; 7 8 import com.opensymphony.xwork2.ActionSupport; 9 10 /** 11 * @author BieHongLi 12 * @version 创建时间:2017年3月6日 上午10:43:52 13 * 上传文件的Action处理 14 * 15 * struts2文件上传 16 * 1:struts2中文件上传拦截器帮助我们完成上传文件的功能; 17 * 18 * 19 */ 20 public class UploadAction extends ActionSupport{ 21 22 private static final long serialVersionUID = 1L; 23 //对应表单的file1 <input type="file" name="file1"/> 24 private File file1; 25 //当前上传的文件名 26 private String file1FileName; 27 //文件类型(MIME) 28 private String file1ContentType; 29 public void setFile1(File file1) { 30 this.file1 = file1; 31 } 32 public void setFile1FileName(String file1FileName) { 33 this.file1FileName = file1FileName; 34 } 35 public void setFile1ContentType(String file1ContentType) { 36 this.file1ContentType = file1ContentType; 37 } 38 39 40 @Override 41 public String execute() throws Exception { 42 //开始拿到上传的文件,进行处理,上传之前,要创建一个upload目录 43 System.out.println("测试上传的文件"); 44 //把文件上传到upload目录,获取上传的目录路径 45 String path=ServletActionContext.getServletContext().getRealPath("/upload"); 46 //创建目标文件对象,文件名file1FileName,格式_FileName 47 File destFile=new File(path,file1FileName); 48 //把上传的文件,拷贝到目标文件中 49 FileUtils.copyFile(file1, destFile); 50 51 return SUCCESS; 52 } 53 54 55 }
5:由于练习阶段,需要很多测试,所以为了方便,特别引入了全局配置,总配置文件和各个项目的配置文件,下面是源码:
在全局配置文件中实现限制上传文件的大小,在分配置文件中实现限制上传文件的类型;
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 <package name="fileuploadpackage" extends="struts-default"> 9 <!-- 定义action --> 10 <action name="fileUploadAction" class="com.bie.upload.UploadAction"> 11 <!-- 显示成功的jsp页面 --> 12 <result name="success">/uploadfile/success.jsp</result> 13 14 <!-- 文件上传拦截器,限制运行上传的文件的类型,还有其他一个方法,这是其中一个 --> 15 <interceptor-ref name="defaultStack"> 16 <!-- 限制运行的文件的扩展名 fileUpload.allowedExtensions固定写法--> 17 <param name="fileUpload.allowedExtensions">txt,jpg,gif,png</param> 18 </interceptor-ref> 19 20 21 <!-- 错误提示,档文件上传出现错误的时候,struts内部会返回input视图, 22 错误视图,所以就需要我们在struts.xml中配置Input视图对应的错误页面 --> 23 <result name="input">/uploadfile/error.jsp</result> 24 25 </action> 26 </package> 27 </struts>
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 9 <!-- 修改上传文件的最大大小为30M --> 10 <constant name="struts.multipart.maxSize" value="31457280"></constant> 11 12 13 </struts>
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 <!-- 一:Struts2的全局配置,必须写在最上面,格式如下所示 --> 8 <include file="constant.xml"></include> 9 10 <!-- 二:总配置文件,引入其他所有配置文件 --> 11 <include file="com/bie/upload/fileupload.xml"></include> 12 13 14 15 </struts>
6:最后完成成功页面和错误页面的跳转,源码如下所示:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>成功的页面</title> 8 </head> 9 <body> 10 成功的页面 11 </body> 12 </html>
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>成功的页面</title> 8 </head> 9 <body> 10 error.jsp 11 <!-- 查询struts2在运行期间产生的所有错误信息 --> 12 <%@ taglib prefix="s" uri="/struts-tags"%> 13 <s:fielderror></s:fielderror> 14 </body> 15 </html>
演示效果如下所示:分别演示了限制不符合文件类型的上传和符合文件类型的上传
struts2实现文件的下载是在上面上传的基础上完成的,所以直接写下载的代码:
1:实现文件的下载,首先创建一个list.jsp页面,用于展示文件,源码如下所示:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 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 <center> 13 <table cellpadding="10" cellspacing="10"> 14 <tr> 15 <td>编号</td> 16 <td>文件名</td> 17 <td>操作</td> 18 </tr> 19 <c:forEach items="${fileNames }" var="fileName" varStatus="fn"> 20 <tr> 21 <td>${fn.count}</td> 22 <td>${fileName }</td> 23 <td> 24 <!-- 构建一个ur --> 25 <c:url var="url" value="down_down"> 26 <c:param name="fileName" value="${fileName }"></c:param> 27 </c:url> 28 <a href="${url }">下载</a> 29 </td> 30 </tr> 31 </c:forEach> 32 </table> 33 34 </center> 35 </body> 36 </html>
2:然后开发Action,创建一个文件DownActin.java,源码如下所示:
1 package com.bie.upload; 2 3 import java.io.File; 4 import java.io.InputStream; 5 import java.io.UnsupportedEncodingException; 6 import java.net.URLEncoder; 7 import java.util.Map; 8 9 import org.apache.struts2.ServletActionContext; 10 11 import com.opensymphony.xwork2.ActionContext; 12 import com.opensymphony.xwork2.ActionSupport; 13 14 /** 15 * @author BieHongLi 16 * @version 创建时间:2017年3月6日 下午1:54:00 17 * 文件下载的2种方式: 18 * 方式1:通过response对象向浏览器写入字节流数据,设置下载的响应头 19 * 方式2:struts的方式 20 */ 21 public class DownAction extends ActionSupport{ 22 23 24 private static final long serialVersionUID = 1L; 25 26 //第一步:显示所有要下载的文件的列表 27 public String list() throws Exception { 28 //1:得到upload目录路径 29 String path=ServletActionContext.getServletContext().getRealPath("/upload"); 30 //2:目录对象 31 File file=new File(path); 32 //3:得到所有要下载的文件的文件名 33 String[] fileNames=file.list(); 34 //4:保存 35 ActionContext ac=ActionContext.getContext(); 36 //5:得到代表request的Map(第二种方式) 37 Map<String,Object> request=(Map<String,Object>)ac.get("request"); 38 39 request.put("fileNames", fileNames); 40 return "list"; 41 } 42 43 //*************2:文件下载************************/ 44 //2.1:获取要下载的文件的文件名,设置字符集,前台页面提交的是以get方式提交的 45 private String fileName; 46 public void setFileName(String fileName) { 47 //处理传入的参数种问题(get提交) 48 try { 49 fileName=new String(fileName.getBytes("ISO8859-1"),"UTF-8"); 50 } catch (UnsupportedEncodingException e) { 51 throw new RuntimeException(); 52 } 53 //把处理好的文件名,赋值 54 this.fileName = fileName; 55 } 56 57 //2.2:下载提交的业务方法(在struts.xml中配置返回stream) 58 public String down() throws Exception { 59 return "download"; 60 } 61 62 //2.3:返回流的方法 63 public InputStream getAttrInputStream(){ 64 return ServletActionContext.getServletContext().getResourceAsStream("/upload/"+fileName); 65 } 66 67 //2.4:下载显示的中文名,(浏览器显示的文件名) 68 public String getDownFileName(){ 69 try{ 70 //import java.net.URLEncoder; 71 fileName = URLEncoder.encode(fileName,"UTF-8"); 72 }catch(Exception e){ 73 throw new RuntimeException(); 74 } 75 76 return fileName; 77 } 78 }
3:接着配置struts.xml的分文件fileupload.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 <package name="fileuploadpackage" extends="struts-default"> 9 <!-- 定义action --> 10 <action name="fileUploadAction" class="com.bie.upload.UploadAction"> 11 <!-- 显示成功的jsp页面 --> 12 <result name="success">/uploadfile/success.jsp</result> 13 14 <!-- 文件上传拦截器,限制运行上传的文件的类型,还有其他一个方法,这是其中一个 --> 15 <interceptor-ref name="defaultStack"> 16 <!-- 限制运行的文件的扩展名 fileUpload.allowedExtensions固定写法 17 allowedExtensions找到allowedExtensionsSet去掉set即可--> 18 <param name="fileUpload.allowedExtensions">txt,jpg,gif,png</param> 19 </interceptor-ref> 20 21 22 <!-- 错误提示,档文件上传出现错误的时候,struts内部会返回input视图, 23 错误视图,所以就需要我们在struts.xml中配置Input视图对应的错误页面 --> 24 <result name="input">/uploadfile/error.jsp</result> 25 26 </action> 27 28 <!-- 下载的action --> 29 <action name="down_*" class="com.bie.upload.DownAction" method="{1}"> 30 <!-- 列表展示 --> 31 <result name="list">/uploadfile/list.jsp</result> 32 33 <!-- 下载操作 --> 34 <result name="download" type="stream"> 35 <!-- 允许下载的文件的类型:指定为所有的二进制的文件类型,去tomcat的wen.xml里面搜索.exe --> 36 <param name="contentType">application/octet-stream</param> 37 <!-- 对应的就是Action种的属性,返回流的属性,【其实就是getAttrInputStream()】 --> 38 <param name="inputName">attrInputStream</param> 39 <!-- 下载头,包括:浏览器显示的文件名 --> 40 <param name="contentDisposition">attachment;filename="${downFileName}"</param> 41 <!-- 缓冲区大小设置 --> 42 <param name="bufferSize">1024</param> 43 </result> 44 45 </action> 46 </package> 47 </struts>
演示效果如下图所示:
下面简单说一下如何找一些配置或者定义好的文件名:
对于框架的要求,不需要研究底层,当然你有精力,可以去研究,对于一个又一个新的框架的产生,我感觉个人能熟练应用和知道底层是如何工作的以及底层的定义名词,这就足够了。
1:首先应该会找到struts-default.xml这个文件,以及配置文件里面的一些配置,如这次使用下载文件所使用的stream流api里面的案例:
2:这次上传文件所使用的过滤器,你也应该能找到,这样才可以会用他们定义好的属性:
革命尚未成功,别先生仍需努力啊!!!