概述
在做B/S架构项目时,经常会遇到文件上传与下载的需求,在struts2框架中帮我们实现的文件上传与下载机制,能够很好地实现项目需求。在使用的时候,需要导入文件上传与下载需要的两个jar,一个是commons-fileupload-x.x.x.jar,另一个是commons-io-x.x.x.jar.
一、文件上传的表单(多文件上传)
在做文件上传时,表单中的method方法必须是post,里边的enctype必须是multipart/form-data。不然会出现莫名其妙的异常。多文件上传的表单通过js技术来做控制。整个上传文件的页面是:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<script type="text/javascript" language="JavaScript"
src="${pageContext.request.contextPath }/script/calendar.js"
charset="gb2312"></script>
<script language="javascript">
function checkf() {
var files = document.getElementsByName("file");
if (files[0].value.length != 0) {
return true;
} else {
alert("请选择文件");
return false;
}
}
//添加一行
function addMore() {
var td = document.getElementById("more");
//换行
var br = document.createElement("br");
var input = document.createElement("input");
var button = document.createElement("input");
input.type = "file";
input.name = "file";
button.type = "button";
button.value = "Remove";
button.onclick = function() {
td.removeChild(br);
td.removeChild(input);
td.removeChild(button);
}
td.appendChild(br);
td.appendChild(input);
td.appendChild(button);
}
</script>
<html>
<head>
<title>测试文件上传的jsp</title>
<link href="${pageContext.request.contextPath }/css/Style.css"
type="text/css" rel="stylesheet">
</head>
<body>
<s:form action="upLoadAction_upload.do" method="post" theme="simple"
enctype="multipart/form-data">
<table align="center" width="50%" border="1">
<tr>
<td>选择上传文件</td>
<td id="more"><s:file name="file"></s:file> <input
type="button" value="Add More.." οnclick="addMore()"></td>
</tr>
<tr>
<td><s:submit type="button" value="submit"
οnclick="return checkf()" /></td>
<td><s:reset value="reset "></s:reset></td>
</tr>
</table>
</s:form>
</body>
</html>
二、文件上传的Action
在文件上传的action中必须要有三个参数,分别是File类型的file-上传的文件;String类型的fileFileName-上传文件的名称;String类型的fileContentType-文件类型。如果是多文件上传,使用List集合去包裹,也就是List<File> file-上传文件集合;List<Sting> fileFileName-文件名称集合;List<String> fileContentType-文件类型集合。
package cn.ysu.zhy.devmanager.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Controller;
@Controller("upLoadAction")
public class UpLoadAction extends BaseAction {
/**
* 1.做文件上传必须得三个参数:file,fileFileName,fileContentType
*/
/**
* 对应jsp的file标签,表示上传的文件(多文件用集合表示)
*/
private List<File> file;
/**
* 文件名称
*/
private List<String> fileFileName;
/**
* 文件的类型
*/
private List<String> fileContentType;
/**
* 2.下载的文件名
*/
private String fileName;
private String fileUploadErrorMessage;
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
public List<String> getFileContentType() {
return fileContentType;
}
public void setFileContentType(List<String> fileContentType) {
this.fileContentType = fileContentType;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* @Name: home
* @Description: 跳转到上传首页upload.jsp
* @Author: ZHY(作者)
* @Version: V1.00 (版本号)
* @Create Date: 2016-10-07 (创建日期)
* @Parameters: 无
* @Return: String 跳转到上传首页upload.jsp
*/
public String home() {
return "home";
}
/**
* @throws Exception
* @Name: upload
* @Description: 处理文件的上传
* @Author: ZHY(作者)
* @Version: V1.00 (版本号)
* @Create Date: 2016-10-07 (创建日期)
* @Parameters: 无
* @Return: String 上传成功,重定向到upload.jsp
*/
public String upload() throws Exception {
// 1.获取上传的文件路径
File filePath = new File(ServletActionContext.getServletContext().getRealPath("myUploadFile"));
// 2.判断目录是否存在,如果不存在创建文件夹
if (!filePath.exists()) {
filePath.mkdir();// 创建目录
}
System.out.println(filePath);
if (file != null && file.size() > 0 && fileFileName != null && fileFileName.size() > 0) {
for (int i = 0; i < file.size(); i++) {
// 3.声明文件的输入流,为输入流指定路径
FileInputStream is = new FileInputStream(file.get(i));
// 获取上传文件的大小(单位是字节1257114280--是1.17G),做数据狭小的限制,如果大于209715200,也就是200M,return
// error,提示上传文件大小不能超过200M,2097152--2M
int length = is.available();// 获取上传文件的字节大小
// 上传的文件超过200M
if (length >= 209715200) {
request.setAttribute("error", "您上传的文件超过200M");
return "error";
}
// 4.获取文件输出流,声明输出流的地址已及名称
FileOutputStream out = new FileOutputStream(filePath + "\" + fileFileName.get(i));
try {
// 5.流对接
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) > 0) {
// 将buffer里的二进制数,从0开始,每次写len这么长,写入输出流中
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
is.close();
out.close();
}
}
}
request.setAttribute("fileName", fileFileName);
return "upload";
}
/**
* @Name: upload
* @Description: 处理文件的下载
* @Author: ZHY(作者)
* @Version: V1.00 (版本号)
* @Create Date: 2016-10-07 (创建日期)
* @Parameters: 无
* @Return: String 下载成功,重定向到upload.jsp
*/
public String download() {
return "download";
}
}
三、文件下载的表单
文件下载相对于文件上传要简单一些,在JSP中唯一需要注意的就是中文乱码问题,解决乱码问题使用URLEncoder和URLDecoder基本上就能解决了。
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<script type="text/javascript" language="JavaScript"
src="${pageContext.request.contextPath }/script/calendar.js"
charset="gb2312"></script>
<html>
<head>
<title>测试文件下载的jsp</title>
<link href="${pageContext.request.contextPath }/css/Style.css"
type="text/css" rel="stylesheet">
</head>
<body>
<table align="center" width="50%" border="1">
<s:if test="#request.fileName != null && #request.fileName.size() > 0">
<s:iterator value="#request.fileName" var="name">
<s:set value="name" id="names" name="names" scope="Request" />
<%
//没有进行编码
String fname = (String) request.getAttribute("names");
//编码之后的值
String fnameEncode = java.net.URLEncoder.encode(fname, "UTF-8");
%>
<tr>
<td><%=fname%></td>
<td><a
href="<s:url value='downLoadAction_download.do'><s:param name='fileName'><%=fnameEncode%></s:param> </s:url>">下载</a>
</td>
</tr>
</s:iterator>
</s:if>
</table>
</body>
</html>
四、文件下载的Action
在文件下载的action中,必须有两个参数,一个是String类型的fileName-文件名称和InputStream类型的fileInput-文件下载的流。
package cn.ysu.zhy.devmanager.action;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Controller;
/**
* 文件下载的action
*
* @author ZHY
*
*/
@Controller("downLoadAction")
public class DownLoadAction extends BaseAction {
/**
* 下载文件的名称
*/
private String fileName;
/**
* 下载的文件
*/
private InputStream fileInput;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
try {
fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
}
public InputStream getFileInput() {
try {
fileName = URLDecoder.decode(fileName, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return ServletActionContext.getServletContext().getResourceAsStream("myUploadFile\" + fileName);
}
public void setFileInput(InputStream fileInput) {
this.fileInput = fileInput;
}
/**
* 下载时,显示中文名字
*
*/
public String getDownloadFileName() {
String downloadFileName = fileName;
try {
// 使用ISO8859-1编码
downloadFileName = new String(downloadFileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downloadFileName;
}
/**
* @Name: download
* @Description: 处理文件的上传
* @Author: ZHY(作者)
* @Version: V1.00 (版本号)
* @Create Date: 2016-10-07 (创建日期)
* @Parameters: 无
* @Return: String 上传成功,重定向到upload.jsp
*/
public String download() {
try {
fileName = URLDecoder.decode(fileName, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
fileInput = ServletActionContext.getServletContext().getResourceAsStream("myUploadFile\" + fileName);
if (fileInput == null) {
return "error";
}
return "download";
}
}
OK了,至此,文件上传与下载的功能就实现了。但是存在一个问题,就是struts2中默认支持能够上传的文件大小是2M,在项目开发过程中,一般上传的文件都要大于2M,这个问题也好解决,只需要在struts.xml中,配置一个constant常量,将文件的最大值设置成想要的。
<!-- 允许文件上传的大小,默认为2M 2097152 在这里设置成自己想要的-->
<constant name="struts.multipart.maxSize" value="2097152"></constant>
五、超出指定上传文件大小之后的提示
在项目中,往往有这种需求:当用户上传的文件大于系统设定的值的时候,需要提示用户,如果直接报错,用户体验非常不好。我在做这部分需求的时候,走了不少弯路,也查阅了大量的网上的资料,但是最终还是遇到了一个跨不过去的坑(对于我来说的,可能是自己知识储备不到位)。
我查阅了很多资料,都是说需要重写action中的addActionError方法,将上传文件的错误转变成action级别的错误,我这样做了,也在addActionError中获取到了相应的文件大小,将错误信息添加到supper.addActionError中之后,无论我如何,在jsp中也获取不到我自己抛出的错误信息,而是页面直接报错了。这个问题困扰了我很久,也跟一些人讨论过,但是最终还是没有一个完美的解释。于是,我想了一个比较笨的方法:
1、首先在constant中配置一个很大的最大值,这个值可以设置的大一点,我这里设置成了2000M;
PS:我主要是最文档文件上传,也就是一些doc、pdf等,一帮不可能超过这么大。我系统中的需求是不能大于200M。
2、在文件上传的action中,获取上传上来的文件的大小,跟200M做一个比较,如果大于200M,那么将错误信息写到request作用域中,然后return error。否则正常执行文件上传的操作。对应代码中的位置:
// 声明文件的输入流,为输入流指定路径
FileInputStream is = new FileInputStream(file.get(i));
// 获取上传文件的大小(单位是字节1257114280--是1.17G),做数据狭小的限制,如果大于209715200,也就是200M,return
// error,提示上传文件大小不能超过200M,2097152--2M
int length = is.available();// 获取上传文件的字节大小
// 上传的文件超过200M
if (length >= 209715200) {
request.setAttribute("error", "您上传的文件超过200M");
return "error";
}
在错误页面中,使用struts的标签,得到自己抛出的错误信息,提示用户。
<s:property value="#request.error" />
PS:我这个测试demo是在SSH框架的基础上进行开发的,所以源码中会涉及到一些hibernate和spring相关的知识。
点我下载Demo
最后
以上就是欢喜大船为你收集整理的struts2文件的上传与下载--超出指定文件大小的校验提示一、文件上传的表单(多文件上传)二、文件上传的Action三、文件下载的表单四、文件下载的Action五、超出指定上传文件大小之后的提示的全部内容,希望文章能够帮你解决struts2文件的上传与下载--超出指定文件大小的校验提示一、文件上传的表单(多文件上传)二、文件上传的Action三、文件下载的表单四、文件下载的Action五、超出指定上传文件大小之后的提示所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复