一、文件上传原理
表单元素的enctype属性执行的是表单元素的编码方式,该属性有三个值;
1)、application/x-www-form-urlencoded:这是默认的编码方式,它只处理表单中的value,采用这种方式的表单会将表单域里的值处理成url编码方式。
2)、multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。
3)、text/plain:这种方式主要适用于直接通过表单发送邮件的方式。
文件上传是通过为表单元素设置enctype=”multipart/form-data”属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
在Java领域中,有两个常用的文件上传项目:一个是Apache组织Jakarta的Common-FileUpload组件:
([url]http://commons.apache.org/fileupload/)
另一个是Oreilly组织的COS框架:
([url]http://www.servlets.com/cos/)。
利用这两个框架都能很方便的实现文件的上传。
二、Struts2下的文件上传
Struts2并没有提供自己的请求解析器,也就是说Struts2不会自己去处理multipart/form-data的请求,它需要调用其 他请求解析器,将HTTP请求中的表单域解析出来。但Struts2在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
Struts2默认使用的是Jakarta的Common-FileUpload框架来上传文件(可以从defaults.properties文件中看到)
因此、我们需要导入两个jar包commons-fileupload.jar和commons-io.jar。它在原上传框架上做了进一步封装,简化了文件上传的代码实现,取消了不同上传框架上的编程差异。
范例:
jsp
<body>
<fieldset>
<legend>文件上传</legend>
<form action="FileUpload_fileUpload.action" method="post" enctype="multipart/form-data">
文件:<input type="file" name="file" />
<input type="submit" value="提交" />
</form>
</fieldset>
</body>
Action
private File file; //上传文件对象
private String fileFileName; //上传文件名
private String fileContentType; //上传文件类型
/**
* 文件上传
* @return
*/
public String upload(){
InputStream is = null;
OutputStream os = null;
//获取要上传到的目录
String path = ServletActionContext.getRequest()
.getServletContext().getRealPath("/files");
try {
is = new FileInputStream(file);
os = new FileOutputStream(new File(path,fileFileName));
byte[] bys = new byte[1024];
int len = 0;
while((len=is.read(bys))!=-1){
os.write(bys, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "fileUpload";
}
//....省略geter/seter
配置
其他的一些配置
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
这些是default.properties中的,我们也可以修改这些配置。
<constant name="struts.multipart.saveDir" value="E:\" />
<constant name="struts.multipart.maxSize" value="20971520" />
通过拦截器的配置限制文件上传的扩展名和文件上传的大小。
上传文件超过大小范围:
这是需要进行国际化错误信息:在核心包中的struts-messsages.properties文件中有这些信息。
新建一个i18n.properties文件进行配置
一些问题总结:
描述:在使用Struts2的文件上传时,文件大小和类型过滤后,页面无法跳转至input页面
原因:文件上传类未继承ActionSupport,导致拦截器的跳转到input页面的功能不能真正使用
描述:文件上传的过滤先后问题
1.先判断表单提交的数据大小,是否超过配置文件“struts.multipart.maxSize”的值(默认大小:2097152 B);
2.再判断上传的文件数据是否超过拦截器里配置的“maximumSize”的大小;
3.最后检查是否文件类型是否满足拦截器的条件;
另外还有一点需要说明的是,有些配置上传过滤器是这样配置的
<interceptor-ref name="fileUpload">
<param name="allowedTypes">
image/bmp,image/png,image/gif,image/jpeg
</param>
<param name="maximumSize">1024000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
因为默认拦截器栈“defaultStack”是包含文件上传拦截器的,所以依拦截的先后顺序,此处文件上传拦截器会执行2次,所以不建议如此配置,合理的做法应该是配置默认拦截器栈,在里面覆盖掉“fileUpload”的属性即可。