struts2 框架下的文件上传和文件下载
在日常的web应用中文件上传和文件下载都是非常普遍的事情,而解决这个问题的方式也是有着很多种。今天我主要是简单介绍一下采用struts2 框架下我们应该怎么实现这两个功能呢。
1. 文件上传
为了在javaEE 应用中实现文件上传功能,需要将表单的method 属性设置为POST 方式,将enctype 属性设置为“multipart/form-data”。
这样做的原因是为了让浏览器把用户选择的文件以二进制数据的形式发送给服务器,使用二进制流的方式来处理请求数据。
(1)编写上传表单文件 upload.jsp ,将属性 enctype 设置为 “multipart/form-data”。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试 Struts2 框架的文件上传功能</title>
</head>
<body>
<h3>测试文件上传功能</h3>
<!-- enctype标签是指定本表单请求参数以二进制的方式发送 -->
<s:form action="upload" enctype="multipart/form-data">
<s:textfield name="title" label="文件标题"></s:textfield><br/>
<!-- 文件选取标签 -->
<s:file name="upload" label="选择文件"></s:file><br/>
<s:submit value="上传"></s:submit>
</s:form>
</body>
</html>
(2)编写文件上传失败文件,uploadInput.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${error }
<br>
<br>
<a href="${pageContext.request.contextPath }/test/upload.jsp">返回上一步</a>
</body>
</html>
(3)编写一个文件上传成功文件,uploadSuccess.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传成功页面</title>
</head>
<body>
<h3>文件上传成功!</h3>
文件标题:<s:property value="+ title"/><br />
文件名:<s:property value="+ uploadFileName"/><br />
文件类型:<s:property value="+ uploadContentType"/><br />
</body>
</html>
(4)编写处理文件上传的Action 类,UplandAction.java
每个上传的文件都会存在这个几个属性
□. 类型为File 的XXX 属性封装了上传文件的文件域对应的内容
□. 类型为String的 xxxFileName 属性封装了上传文件的文件名
□. 类型为String 的 xxxContentType 属性封装了上传文件的文件类型
通过这三个属性,可以简单的地实现文件上传,可以通过属性的set方法接收上传文件的信息,通过get方法获取上传文件的信息。
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
//封装文件标题请求参数的属性
private String title;
//封装上传文件内容的属性
private File upload;
//封装上传文件类型的属性
private String uploadContentType;
//封装上传文件名的属性
private String uploadFileName;
//在服务器存放用户上传文件的路径,直接在struts.xml 文件中配置的属性
private String savePath;
//封装允许上传文件的文件类型
private String allowTypes;
//封装允许上传文件的大小值
private Long maximumSize;
//设置属性的get/set方法
public Long getMaximumSize() {
return maximumSize;
}
public void setMaximumSize(Long maximumSize) {
this.maximumSize = maximumSize;
}
public String getAllowTypes() {
return allowTypes;
}
public void setAllowTypes(String allowTypes) {
this.allowTypes = allowTypes;
}
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.getServletContext().getRealPath(savePath);
// return savePath;
}
//接收struts.xml 文件配置值的方法
public void setSavePath(String savePath) {
this.savePath = savePath;
}
@Override
public String execute() throws Exception {
System.out.println(getAllowTypes());
System.out.println("进入成功!");
//获取得到过滤文件的结果
String result = FilterType();
if(result.equals("pass")) {
if(getUpload() != null && (upload.length() > maximumSize)) {
ActionContext.getContext().put("error", "对不起,您不能上传太大的文件!");
return INPUT;
} else {
// 以文件保存路径 + 文件名建立上传文件的输出流存放点
FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadFileName());
//以用户的上传文件建立上传文件输出流对象
FileInputStream fis = new FileInputStream(getUpload());
//设置以字节格式存放,以及每个字节的大小
byte[] buffer = new byte[1024];
//定义一个存放文件字节数的变量
int len = 0;
//把用户上传文件以字节流的方式存放到服务器中
while((len = fis.read(buffer))> 0 ) {
fos.write(buffer,0,len);
}
//关闭流
fos.close();
return SUCCESS;
}
} else {
ActionContext.getContext().put("error", "对不起,您不能上传此类型的文件!");
return INPUT;
}
}
//提供一个手动过滤上传文件类型的方法
public String FilterType() {
//获取得到上传文件的文件类型
String fileType = getUploadContentType();
//获取得到系统运行上传文件的文件类型
String [] types = getAllowTypes().split(",");
//遍历文件类型数组
for(String type:types) {
System.out.println(type);
if(type.equals(fileType)) {
return "pass";
}
}
return "not";
}
}
(5)设计对Action类的映射配置文件,struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"></constant>
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<package name="struts2" namespace="/" extends="struts-default">
<!-- 文件上传Action -->
<action name="upload" class="test.UploadAction" method="execute">
<param name="savePath">/place</param>
<param name="allowTypes">text/plain,application/octet-stream,text/html</param>
<param name="maximumSize">3072</param>
<result>/test/uploadSuccess.jsp</result>
<result name="input">/test/uploadInput.jsp</result>
</action>
</package>
</struts>
(6)在web应用类加载路径下编写Struts2 框架的核心拦截Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>chapter03</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>
<!-- 定义filter -->
<filter>
<filter-name>struts2</filter-name>
<!-- filter的实现类,此处是Struts2的核心过滤器 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<!-- filter的名字,必须是filter元素中已经声明过的过滤器的名字 -->
<filter-name>struts2</filter-name>
<!-- 定义filter负责拦截的URL地址 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
到此对于struts2 的文件上传功能基本完成
2. 文件下载
在Suts2应用中,通过结果类型 stream来支持文件下载功能。当指定 stream结果类型时,需要设置一个 inputname作为输入流,这个输入流是被下载文件的入口。通过Struts2的文件下载支持,允许系统控制浏览者下载文件的权限,包括实现下载名为非西欧字符的文件(即对中文或者其他非英文字符的乱码问题的处理)。
(1)编写一个文件下载的连接,download.jsp
链接上的下载文件必须在服务器上能找得到,比如
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>测试struts2 文件下载功能</h3>
<ul>
<li>
<a href="/chapter03/download.action?filename=小酒窝MV.mp4">下载</a>
</li>
</ul>
</body>
</html>
(6)在web应用类加载路径下编写Struts2 框架的核心拦截Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>chapter03</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>
<!-- 定义filter -->
<filter>
<filter-name>struts2</filter-name>
<!-- filter的实现类,此处是Struts2的核心过滤器 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<!-- filter的名字,必须是filter元素中已经声明过的过滤器的名字 -->
<filter-name>struts2</filter-name>
<!-- 定义filter负责拦截的URL地址 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
(3)设计文件下载的处理Action类,DownloadAction.java。
struts2 的文件下载与普通Action的文件下载并没有太大的区别,仅仅是该Action需要提供一个返回InputStream 流的方法,该输入流代表了被下载文件的入口。
关键是需要配置一个类型为Stream的结果,该stream类型的结果将使用文件下载作为响应。在配置stream 类型的结果时,需要指定如下属性。
□. contentType:指定被下载文件的文件类型
□. inputName:指定被下载文件的入口输入流
□. contentDisposition:指定被下载文件的文件名
□. bufferSize:指定下载文件时的缓冲大小
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownAction extends ActionSupport{
private static final long serialVersionUID = 1L;
//封装下载文件的文件名
private String filename;
//封装下载文件的文件类型
private String contentType;
public String getContentType() throws UnsupportedEncodingException{
return ServletActionContext.getServletContext().getMimeType(getFilename());
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getFilename() throws UnsupportedEncodingException {
//解决get乱码问题
// return encodeDownloadFilename(filename,ServletActionContext.getRequest().getHeader("User-Agent"));
return filename;
}
public void setFilename(String filename) throws UnsupportedEncodingException {
//解决中文乱码问题
// filename = URLDecoder.decode(filename, "utf-8");
// filename = new String(filename.getBytes("iso8859-1"),"utf-8");
this.filename = filename;
}
//获取得到inputStream 被下载文件的输入流
public InputStream getInputStream() throws FileNotFoundException, UnsupportedEncodingException {
//由文件的绝对路径和文件名组成的文件输入流
return new FileInputStream(new File(ServletActionContext.getServletContext().getRealPath("\\image"),getFilename()));
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println("下载文件时:"+getFilename());
System.out.println("下载文件类型:"+getContentType());
return SUCCESS;
}
}
(5)设计对Action类的映射配置文件,struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"></constant>
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<package name="struts2" namespace="/" extends="struts-default">
<!-- 问价下载的action -->
<action name="download" class="test.DownAction">
<result name="success" type="stream">
<!-- 指定被下载文件的文件类型 -->
<param name="contentType">${contentType}</param>
<!-- 指定被下载文件的输入流,交给框架 -->
<param name="inputName">inputStream</param>
<!-- 指定被下载文件的文件名 -->
<param name="contentDisposition">attachment;filename="${filename}"</param>
</result>
</action>
</package>
</struts>
本次章节到此结束,如有问题多多赐教
本篇文章内容是本人在《javaEE 企业级开发》学习Struts框架时做的笔记