文件上传是WEB应用经常需要面对的问题。在大部分时候,用户的请求参数是在表单域输入的字符串,但如果为表单元素设置enctype=“multipart/form-data”属性,则提交表单时候不再是以字符串方式提交请求参数,而是以二进制编码的方式提交请求,此时直接通过HttpServletRequest的getParameter方法就无法正常获取请求参数的值,而通过二进制流来获取请求内容,就可以获取到上传文件的内容,从而实现文件上传的功能。
Struts2的文件上传支持在原有的文件上传项目上做了进一步的封装,只需要将属性封装表单的文件域,就可非常轻松地完成文件上传。
一、首先讲解一下,在页面中标签form表单中的属性:
1)action属性指定了表中提交的URL;
2)method属性指定是以POST方式还是GET方式提交请求;
3) Enctype属性指的是表单数据的编码方式,该属性有如下3个值:
application/x-www-form-urlencoded:默认编码方式,它只处理表单 里的value属性值。
multipart/form-data:指的是以二进制流的凡是来处理表单数据,这 种方式会把文件或者文件的内容也封装到请求参数里。
text/plain:当表单的action属性为mailto:url的形式时比较方便, 这种方式主要适用于直接通过表单发送邮件的方式。
二、使用Struts2完成文件上传
1.前端页面必须满足条件
1) 必须同步提交 form 表单
2) Form 表单编码方式 multipart/form-data
3) 提交方式必须为 post
4) 上传文件对应 标签input type=”file” 元素要提供 name 属性
演示代码:
<%@ 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完成文件上传</title>
</head>
<body>
<!-- 为了完成文件上传:
1)标签form表单设置enctype=“multipart/form-data”属性;
2)表单为同步提交方式 method="post";
3)上传文件对应 标签input type=”file” 元素要提供 name 属性
-->
<form action="${pageContext.request.contextPath}/fileUpload"
enctype="multipart/form-data" method="post">
文件标题:<input type="text" name="title" /><br />
选择文件:<input type="file" name="uploadObj" /><br />
<input type="submit" value="上传" />
</form>
</body>
</html>
2.服务器端Action注意事项
1)提供文件上传的三个属性
private File xxx 该属性封装了该文件域对应的文件内容;
private xxxFileName 该属性封装了该文件与对应的文件的文件名;
private xxxContentType 该属性封装了该文件与对应的文件的文件类型;
UploadAction中代码演示:
package cn.struts2.action.upload;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
//继承ActionSupport为了接受页面其他参数;
public class FileUploadAction extends ActionSupport {
private File uploadObj; // 上传文件对象
private String uploadObjFileName; // 上传文件名称
private String uploadObjContentType;// 上传文件类型
private String title; // 页面表单中参数
public File getUploadObj() {
return uploadObj;
}
public void setUploadObj(File uploadObj) {
this.uploadObj = uploadObj;
}
public String getUploadObjFileName() {
return uploadObjFileName;
}
public void setUploadObjFileName(String uploadObjFileName) {
this.uploadObjFileName = uploadObjFileName;
}
public String getUploadObjContentType() {
return uploadObjContentType;
}
public void setUploadObjContentType(String uploadObjContentType) {
this.uploadObjContentType = uploadObjContentType;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// 完成文件上传的方法
public String uploadFile() {
try {
// 获取服务器端upload文件夹目录的绝对磁盘路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
// 创建一个服务文件
File file = new File(path,uploadObjFileName);
//使用struts2的封装的工具FileUtils,完成文件上传
FileUtils.copyFile(uploadObj, file); //传递文件对象和目标路径
//将文件标题和上传文件路径存入值栈
ValueStack vs = ActionContext.getContext().getValueStack();
vs.set("title", title);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("上传文件失败");
}
return SUCCESS;
}
}
3.在配置Struts.xml文件上传的Action与配置普通Action并没有太大的区别,一样是指定该Action的name,以及该Action的实现类。
当然,还应该为该Action配置<result .../>元素。
代码演示:
<!-- 配置页面请求路径和访问到Action中的方法 --> <package name="default" namespace="/" extends="struts-default"> <action name="fileUpload" class="cn.struts2.action.upload.FileUploadAction" method="uploadFile"> <result name="success" >/success.jsp</result> </action>
4.最后web.xml文件的配置:
1)定义struts2的核心filter
2)定义Struts2核心Filter拦截的URL
<?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>struts_demo</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> <!-- 定义struts2的核心filter --> <filter-name>struts2Filter</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <!-- 定义Struts2核心Filter拦截的URL--> <filter-mapping> <filter-name>struts2Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
5.完成这些配置后,如果我们在页面点击选择文件,并游览到需要上传的文件,然后单击“上传”按钮,该上传请求将被UploadAction处理,处理结束后转入success.jsp页面,该页面使用了简单的Struts2标签来显示文件上传。
success.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>
<h2>上传文件成功!</h2>
<!-- 输出表单中上传文件的标题属性的名称和文件内容 -->
文件标题:<s:property value="title" ></s:property><br>
文件:<img src="<s:property value='file'></s:property>" style="width: 200px;height: 200px">
</body>
</html>
通过以上案例,文件大小限制、文件类型处理等问题,我们如何来解决呢?
1)实现文件过滤
在action中设置拦截器;并其设置属性的值,实现相关的功能(可以拦截上传指定类型的文件--否则给用户跳转到提示页面)
或者在配置文件声明常量:
<constant name=”struts.multipart.maxSize” value=”209715200”></contant>
注释说明:
如果在struts.xml文件中,导入自定义的拦截器,那么同时也要将默认的拦截器defaultStack导入。
如果在单数设置某个action的上传文件大小,超过了系统默认大小是不起作用的。
来源:https://www.cnblogs.com/blogslee/p/6849721.html