Struts2实现文件上传
文件上传是web应用里面常用的功能,在网页上传照片、使用在线OA传递文档至服务器等。大家应该学过JSP中关于Apache下面的commons子项目的FileUpload组件来实现文件上传的功能。那么在struts2是如何实现文件上传的,实际上我们前面刚刚讲过,上传功能在Struts2的框架中已经定义好了专用拦截器,并且已经配置到了默认的执行功能中。我们只需要在程序中编写少量代码就可以实现该功能。话不多说,我开始给大家实现这个功能吧。
一:实现单文件上传
准备工作:准备jar包,Struts2上传功能依赖两个Jar包:commmons-fileupload-x.x.x.jar、conmons-io-x.x.x.jar。(其他的jar包我就不一一讲述了)导入到项目中。
1.上传页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Struts2上传案例</title>
</head>
<body>
<!-- 注意上传的表单必须要加上enctype="multipart/form-data"属性 -->
<form action="uploadAction" method="post" enctype="multipart/form-data">
请输入姓名:<input type="text" name="username"/><br>
请选择您的肖像:<input type="file" name="picture"/><br>
<input type="submit" value="确定"/>
</form>
</body>
</html>
2.开发实现文件上传的Action
代码如下
package com.wsz.action;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
/**
* 上传功能的Action案例
* @author 完善者_
*/
// 定义如下三个属性分别代表上传的文件对象、文件名,以及文件类型
// 规则是与表单的上传文件控制name一致
private File picture;
private String pictureFileName;
private String pictureContentType;
public File getPicture() {
return picture;
}
public void setPicture(File picture) {
this.picture = picture;
}
public String getPictureFileName() {
return pictureFileName;
}
public void setPictureFileName(String pictureFileName) {
this.pictureFileName = pictureFileName;
}
public String getPictureContentType() {
return pictureContentType;
}
public void setPictureContentType(String pictureContentType) {
this.pictureContentType = pictureContentType;
}
/*
* 上传的实现,这里已经非常简单了,struts2的拦截器已经把上传后的文件赋给了picture对象 直接利用commons-io
* 包中的FileUtils的copyFile方法将文件拷贝到服务器指定的目录下即可
* 在这里我们自己在WebRoot下创建一个上传文件的保存目录:uploadfiles
*/
public String upload() {
// 获取uploadfiles目录在服务器上的绝对路径,这里利用了ServletActionContext对象
String path = ServletActionContext.getServletContext().getRealPath(
"uploadfiles");
try {
// 拷贝文件
FileUtils.copyFile(picture, new File(path + "/" + pictureFileName));
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}
}
需要注意的是:在Action中定义了以下三个属性来封装上传文件信息。
- File类型的XXX属性:XXX要与表单中的File控件的name属性一致(以下一样),用于封装File控件对应的文件内容。
- String类型的XXXFileName属性:XXX与前面一样,后面跟FileName,注意是固定语法,其作用是封装File控件对应文件的文件名。
- String类型的XXXContentType属性:XXX与前面一样,后面跟ContentType,也是固定语法,其作用是封装File控件对应文件的文件类型。
有了这三个属性,那么在执行文件上传时就可以直接通过getXxx()方法来获取上传文件名、类型及文件内容。其实背后就是拦截器的功劳。Struts2的文件上传拦截器会自动将上传文件各项信息自动填入到Action的这三个属性中。
Action编写完毕后,下一步就需要配置,配置Action的方式很简单跟以前没什么区别,代码如下。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="fileupload" extends="struts-default">
<action name="uploadAction" class="com.wsz.action.UploadAction" method="upload">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
最后编写一个success页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>跳转成功的jsp界面</title>
</head>
<body>
上传成功!
</body>
</html>
配置好Action后,可以运行界面来测试效果,如图所示。
点击“确定”后,在服务器的Web应用的uploadfiles目录下,可以看到上传的文件已经保存进去了。
如果文件中存在你刚上传的图片则证明你上传成功,否则上传失败。
二:实现多文件上传
实现多文件上传的功能非常简单,在表单中添加多个相同的name属性的文件域的控件,当表单提交时,将会数组类型数据提交。在Action中将原本处理单个文件的操作改成对集合的操作即可。
修改实现文件上传的Action,以满足多文件上传,代码如下。
package com.wsz.action;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
/**
* 上传功能的Action案例
*
* @author 完善者_
*/
// 定义如下三个属性分别代表上传的文件对象、文件名,以及文件类型
// 规则是与表单的上传文件控制name一致
private List<File> picture;
private List<String> pictureFileName;
private List<String> pictureContentType;
public List<File> getPicture() {
return picture;
}
public void setPicture(List<File> picture) {
this.picture = picture;
}
public List<String> getPictureFileName() {
return pictureFileName;
}
public void setPictureFileName(List<String> pictureFileName) {
this.pictureFileName = pictureFileName;
}
public List<String> getPictureContentType() {
return pictureContentType;
}
public void setPictureContentType(List<String> pictureContentType) {
this.pictureContentType = pictureContentType;
}
/*
* 上传的实现,这里已经非常简单了,struts2的拦截器已经把上传后的文件赋给了picture对象 直接利用commons-io
* 包中的FileUtils的copyFile方法将文件拷贝到服务器指定的目录下即可
* 在这里我们自己在WebRoot下创建一个上传文件的保存目录:uploadfiles
*/
public String upload() {
// 获取uploadfiles目录在服务器上的绝对路径,这里利用了ServletActionContext对象
String path = ServletActionContext.getServletContext().getRealPath(
"uploadfiles");
try {
// 拷贝文件
for(int i=0;i<picture.size();i++){
FileUtils.copyFile(picture.get(i), new File(path + "/" + pictureFileName.get(i)));
}
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}
}
JSP页面代码如下。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Struts2上传案例</title>
</head>
<body>
<!-- 注意上传的表单必须要加上enctype="multipart/form-data"属性 -->
<form action="uploadAction" method="post" enctype="multipart/form-data">
请输入姓名:<input type="text" name="username"/><br>
请选择您的肖像 1:<input type="file" name="picture"/><br>
请选择您的肖像 2:<input type="file" name="picture"/><br>
请选择您的肖像 3:<input type="file" name="picture"/><br>
<input type="submit" value="确定"/>
</form>
</body>
</html>
配置好Action后,可以运行界面来测试效果,如图所示。
点击“确定”后,在服务器的Web应用的uploadfiles目录下,可以看到上传的文件已经保存进去了。
这里我就不一一截图了,运行结果和上述结果一致。
Struts2实现文件下载
Struts2可以实现文件上传,也可以实现文件下载,而且相对于文件上传功能来说,文件下载更简单。为了实现下载,Struts2框架提供了stream结果类型的result,该类型就是专门用于实现文件下载功能的。
1.stream结果类型
stream结果类型代表的是一个文件流,在实现时需要指定一个输入流,即inputStream参数,通过这个数据流就可以向客户端输出下载的文件内容。当然,实现文件下载时还要对相关的参数进行配置,例如:MIME类型、HTTP请求头信息、缓冲区的大小等。
stream结果类型的配置参数如下表所示。
名 称 | 作用 |
contentType | 设置浏览器的MIME类型 |
contentLength | 设置文件大小 |
contentDisposition | 设置响应的HTTP头信息中Contentp-Disposition参数的值 |
inputName | 指定Action中提供的inputStream类型的属性名称 |
bufferSize | 设置读取和下载文件的缓冲区大小 |
2.实现文件下载
由于Struts2框架支持文件下载功能,所以实现过程比较简单。
Struts2中实现文件下载时需要用到InputStream,所以在文件下载的Action中需要提供一个获取该InputStream的方法,通过这个流对象可以获取希望下载的文件内容。代码入下。
package com.action;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownloadAction extends ActionSupport{
/**
* 下载的Action
* @author 完善者_
*/
private String filename; //下载的文件名
private InputStream input=null; //用输入流的形式接图片
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public InputStream getInput() {
return input;
}
public void setInput(InputStream input) {
this.input = input;
}
public String execute(){
//将图片转化为流的形式并接收
input=ServletActionContext.getServletContext().getResourceAsStream("/downloads/test.jpg");
return "success";
}
}
在示例中,通过Context上下文获得下载文件的实际路径,并构成一个InputStream输入流,实现文件的下载读取。注意要在目录下面要放入下载的文件,以便测试。
在配置文件中,同样要对下载Action进行设置,并且对stream结果类型的参数进行设置,具体代码如下。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="HZJC" extends="struts-default" namespace="/">
<action name="download" class="com.action.DownloadAction">
<!-- 设定result类型为 Stream -->
<result name="success" type="stream">
<!-- 设定下载的文件类型 -->
<param name="contentType">image/jpeg</param>
<!-- 指定inputStream的属性也就是Action中的inputStream属性 -->
<param name="inputName">input</param>
<!-- 以附件的方式提示下载 {filename表示获取Action中的filename的属性值} -->
<param name="contentDisposition">attachment;filename="${filename}"</param>
</result>
</action>
</package>
</struts>
最后编写一个简单的下载功能页面,在页面中只需要设置一个超链接,通过超链接请求下载的Action,代码入下。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>下载界面</title>
</head>
<body>
<a href="download">下载文件</a>
</body>
</html>
测试:当点击超链接时,将出现下载提示框,运行效果如下图所示。
出现上面提示信息就证明你的下载功能已经实现了。。。
好啦,今天的内容就到这里,我还会持续更新的。。。