一、前言
在之前的随笔之中,我们已经了解Java通过上传组件来实现上传和下载,这次我们来了解Struts2的上传和下载。
注意:文件上传时,我们需要将表单提交方式设置为"POST"方式,并且将enctype属性设置为"multipart/form-data",该属性的默认值为"application/x-www-form-urlencoded",就是说,表单要写成以下这种形式:
<form action="" method="post" enctype="multipart/form-data"></form>
而且Struts2中并没有提供自己的文件上传解析器,默认使用的是Jakarta的Common-FileUpload的文件上传组件,所以我们还需要在添加两个包:
commons-io
commons-fileupload
至于版本根据自己需要选择(笔者在第一篇已经搭建好环境了。地址)
注意点如下:
1.1、文件上传的前提是表单属性method="post" enctype="multipart/form-data";
1.2、web应用中必须包含common-fileupload.jar和common-io.jar,因为struts2默认上传解析器使用的是jakarta;
1.3、可以在struts.xml中配置最大允许上传的文件大小:<constant name="struts.multipart.maxSize" value="....."/>,默认为2M;
二、文件上传案例
2.1、在Action中定义属性:
private File upload; //包含文件内容
private String uploadFileName; //上传文件的名称;
private String uploadContentType; //上传文件的MIME类型;
这些属性都会随着文件的上传自动赋值;
2.2、上传图片的例子
新建视图界面:Upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts2 FileUpload</title> </head> <body> <form action="fileupload" method="post" enctype="multipart/form-data"> 文件标题:<input type="text" name="title"/><br/> 选择文件:<input type="file" name="upload"/><br/> <input type="submit" value="上传"/> </form> </body> </html>
新建UploadAction继承ActionSupport
package com.Struts2.load; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; //上传单个文件 public class UploadAction extends ActionSupport { //文件标题请求参数的属性 private String title; //上传文件域的属性 private File upload; //上传文件类型 private String uploadContentType; //上传文件名 private String uploadFileName; //接受依赖注入的属性 private String savePath; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } //返回上传文件的保存位置 public String getSavePath() { return ServletActionContext.getRequest().getRealPath(savePath); } //接受依赖注入的方法 public void setSavePath(String savePath) { this.savePath = savePath; } public String execute() throws Exception{ System.out.println(getSavePath()); System.out.println(getUploadFileName()); //以服务器的文件保存地址和原文件名建立上传文件输出流 FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadFileName()); //以上传文件建立一个文件上传流 FileInputStream fis = new FileInputStream(getUpload()); //将上传文件的内容写入服务器 byte[] buffer = new byte[1024]; int leng = 0; while((leng=fis.read(buffer))>0){ fos.write(buffer,0,leng); buffer = new byte[1024]; } return SUCCESS; } }
struts.xml配置文件中部署
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--文件上传 --> <package name="default" extends="struts-default"> <action name="fileupload" class="com.Struts2.load.UploadAction"> <!--使用拦截器过滤:1、配置默认拦截器,2、配置input的逻辑视图--> <interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg,image/jpg,/image/gif,image/png</param> </interceptor-ref> <!-- 必须显示配置defaultStack拦截器的引用 --> <interceptor-ref name="defaultStack"/> <param name="savePath">/upload</param> <result name="success">succ.jsp</result> <!--必须配置input的逻辑视图 --> <result name="input">Error.jsp</result> </action> <struts>
注意:web.xml中需要配置struts2的拦截器
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<?xml version="1.0" encoding="UTF-8"?> <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"> <display-name>LearStruts2</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!--为Struts2定义一个过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
succ.jsp视图代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>上传成功</title> </head> <body> 上传成功<br/> 文件标题:<s:property value="title"/><br/> <s:property value="uploadFileName"/> 文件为:<img src="<s:property value="'/LearStruts2/upload/'+uploadFileName"/>"/><br/> </body> </html>
Error.jsp视图代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error 界面</title> </head> <body> <s:fielderror/> </body> </html>
代码效果如下:
注意:在struts.xml配置文件中,已经限制只能上传图片格式,如果上传别的文件的话,则会报错。
2.3、多个文件上传
新建Upliads.jsp
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>上传多个文件</title> </head> <body> <form action="filesupload" method="post" enctype="multipart/form-data"> 文件标题:<input type="text" name="title"><br/> 选择第一个文件:<input type="file" name="uploads"><br/> 选择第二个文件:<input type="file" name="uploads"><br/> 选择第三个文件:<input type="file" name="uploads"><br/> <input type="submit" value="上传"/> </form> </body> </html>
新建UploadsAction类继承ActionSupport
package com.Struts2.load; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; //上传多个文件 public class UploadsAction extends ActionSupport { private String title; //对应jsp的title private File[] uploads; //对应jsp的uploads private String[] uploadsContentType; private String[] uploadsFileName; //savePath:通过配置文件进行赋值"'\'upload", //其中的'\'表示项目的根目录D:\\tomcat-8.0\\wtpwebapps\\LearStruts2\\upload private String savePath; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public File[] getUploads() { return uploads; } public void setUploads(File[] upload) { this.uploads = upload; } public String[] getUploadsContentType() { return uploadsContentType; } public void setUploadsContentType(String[] uploadsContentType) { this.uploadsContentType = uploadsContentType; } public String[] getUploadsFileName() { return uploadsFileName; } public void setUploadsFileName(String[] uploadsFileName) { this.uploadsFileName = uploadsFileName; } public String getSavePath() { return ServletActionContext.getRequest().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } public String execute() throws Exception{ File[] files = getUploads(); for(int i = 0;i<files.length;i++){ System.out.println(getSavePath()); System.out.println(getUploadsFileName()[i]); //getSavePath : 获得根目录 //getUploadsFileName() : 获得文件名 FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadsFileName()[i]); FileInputStream fis = new FileInputStream(files[i]); byte[] buffer = new byte[1024]; int len = 0; while((len=fis.read(buffer))>0){ fos.write(buffer,0,len); buffer = new byte[1024]; } } return SUCCESS; } }
struts.xml中配置信息
<!--多个文件上传 --> <action name="filesupload" class="com.Struts2.load.UploadsAction"> <!--该属性是依赖注入:通过配置文件给savePath赋值 ,是必须的 --> <param name="savePath">/upload</param> <result name="success">succ1.jsp</result> </action>
succ1.jsp
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>多个文件上传</title> </head> <body> 上传成功 </body> </html>
代码效果如下:
2.3、Struts2的文件下载
视图下载界面
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts 2实现的文件下载</title> </head> <body> <a href="down.action">图片下载</a> </body> </html>
Action类
package com.Struts2.load; import java.io.InputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownAction extends ActionSupport { private String inputPath; private String contentType; private String filename; public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } //下载用的Action应该返回一个InputStream实例 //该方法对应在result里的inputName属性值为targetFile //第二步 public InputStream getTargetFile() throws Exception{ System.out.println("1"); InputStream in=ServletActionContext.getServletContext().getResourceAsStream(inputPath); return in; } //第一步 public String execute(){ System.out.println("???"); inputPath="/upload/1.jpg";//要下载的文件名称 filename="1.jpg"; //保存文件时的名称 contentType="image/jpg";//保存文件的类型 return SUCCESS; } }
Struts.xml配置文件
<!-- 下载文件的Action --> <action name="down" class="com.Struts2.load.DownAction"> <!-- 指定被下载资源的位置 --> <param name="inputPath">${inputPath}</param> <!-- 配置结果类型为stream的结果 --> <result name="success" type="stream"> <!-- contentType:指定下载文件的类型 ,和互联网MIME标准中的规定类型一致, 例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片 --> <param name="contentType">${contentType}</param> <!-- 指定下载文件的位置 --> <!-- inputName:下载文件的来源流,对应着action类中某个类型为Inputstream的属性名, 例如取值为inputStream的属性需要编写getInputStream()方法 --> <param name="inputName">targetFile</param> <!-- contentDisposition 文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式, 而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。 默认情况是代表inline,浏览器会尝试自动打开它 --> <param name="contentDisposition">attachement;filename="${filename}"</param> <!-- 指定下载文件的缓冲大小 --> <param name="bufferSize">50000000</param> </result> </action>
代码都有笔者测试过,至于解析,笔者会在后期理解好之后再重新写。