struts2上传文件(Common-FileUpload)
2017-02-02 22:39
399 查看
1.准备工作。
Struts2,默认使用的就是Common-FileUpload的文件上传框架,想要使用这个框架的话,需要将两个JAR文件导入到项目中,分别是:commons-io-2.4.jar和commons-fileupload-1.3.2.jar(将这两个包复制到WEB-INF\lib路径下)。导入完所需要的JAR包之后,就可以使用该框架进行文件的上传工作。
2.表单的支持。
在表单中需要指定enctype属性为:multipart/form-data。其他的属性可以见:http://www.zgguan.com/doc/w3c/tags/att_form_enctype.asp.htm
所以使用struts2所编写的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>Insert title here</title> </head> <body> <s:form action="upload" enctype="multipart/form-data"> <s:file name="upload" label="ChooseFile"></s:file> <s:submit value="Submit"></s:submit> </s:form> </body> </html>
这里使用了struts2中的s标签。也可以单纯的是用html表单,但是method方法需要设置为:post。
<form action="upload.action" enctype="multipart/form-data" method="post"> 选择文件:<input type="file" name="upload"> <input type="submit" value="Submit"> </form>
3.Action处理文件。
如果表单的部分设置完成之后,那么下一步就是需要对上传过来的文件进行接收保存之类的处理了。建立一个Action,处理文件的部分如下:
package hellostruts; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Set; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class upload extends ActionSupport { private String title; private File upload; private String uploadContentType; private String uploadFileName; private String savePath; public void setSavePath(String value) { this.savePath = value; } private String getSavePath() throws Exception { return "F:\\file"; } public void setUpload(File upload) { this.upload = upload; } public File getUpload() { return this.upload; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadContentType() { return this.uploadContentType; } public void setUploadFileName(String uploadName) { this.uploadFileName = uploadName; } public String getUploadFileName() { return this.uploadFileName; } @Override public String execute() throws Exception { // TODO Auto-generated method stub FileOutputStream fileOutputStream = new FileOutputStream(getSavePath() + "\\" + getUploadFileName()); System.out.print(getUploadContentType() + getUploadFileName()); FileInputStream fileInputStream = new FileInputStream(getUpload()); byte[] buffer = new byte[1024]; int len = 0; while((len = fileInputStream.read(buffer)) > 0) { fileOutputStream.write(buffer,0,len); } return SUCCESS; } }
这里的setter和getter都是一般Action中所必须包含的内容。
其中的setSavePath方法,是从struts.xml中或许参数值的(这里并没有什么用。。。因为getSavePath中直接返回了“F:\\file”)。
其他三对setter和getter方法都有特定的格式:
如果表单中包含一个name属性为xxx的文件域,那么对应的Action需要使用三个成员变量来封装该文件域的信息:
类型为File的xxx成员变量封装了该文件域对应的文件内容。(就是上述的setUpload(File upload)方法和getUpload()方法)。
类型为String的xxxFileName成员变量封装了该文件域对应的文件的文件类名。(就是上述的setUploadFileName(String uploadName)和getUploadFileName()方法)。
类型为String的xxxContentType成员变量封装了该文件域对应的文件类型。(就是上述的setUploadContentType(String uploadContentType)和getUploadContentType()方法)。
当有文件上传时,会自动的调用这个setter方法进行设置。
然后再execute中调用相关方法对文件进行保存操作即可。
然后配置struts.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <include file="struts-default.xml"></include> <!-- 指定默认编码集 --> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <!-- 指定需要Struts2处理的请求后缀 --> <constant name="struts.action.extension" value="do,action"></constant> <!-- 设置浏览器是否缓存静态内容,开发阶段应关闭,生产阶段打开,默认为打开 --> <constant name="struts.serve.static.browserCache" value="false"></constant> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认为false,开发阶段应打开 --> <constant name="struts.configuration.xml.reload" value="true"></constant> <!-- 开发模式下使用,可以打印出更详细的错误信息 --> <constant name="struts.devMode" value="true"></constant> <!-- action全部用注解进行配置 --> <!-- 是否开启动态方法调用 --> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!--添加包 --> <package name="hellostruts" extends="struts-default"> <action name="upload" class="hellostruts.upload"> <result>success.jsp</result> </action> </package> </struts>
测试结果:
选择一个txt文件测试。
点击上传。
可以在相对应的路径下面看到该文件已经成功上传保存,如果文件过大的话可能上传失败。。。
4.拦截部分文件。
1.自定义方法拦截。顾名思义,就是自己写一个方法,然后在里面写一些支持上传的文件的类型等信息,然后调用该方法来检测所上传的文件是否合法。
例子:
在上述例子中,加入了一个新的String类型的变量用来检测所上传文件类型是否合法。
private String allowTypes; public void setAllowTypes(String allowTypes) { this.allowTypes = allowTypes; } public String getAllowTypes() { return this.allowTypes; }
这里的setAllowTypes直接从struts.xml中获取参数变量。
所以这里的struts.xml中对应的action内容为:
<action name="upload" class="hellostruts.upload"> <param name="allowTypes">text/plain,img</param> <result>success.jsp</result> <result name="input">error.jsp</result> </action>
添加一个param标签,name属性设置为String变量的名字,后面的参数就是该变量的值,会自动调用setter方法的。
然后编写一个自定义拦截方法:
public String filterTypes(String[] types) { String filtType = getUploadContentType(); System.out.print(filtType); for(String type : types) { if(type.equals(filtType)) { return null; } } return ERROR; } @Override public void validate() { String filterResult = filterTypes(getAllowTypes().split(",")); if (filterResult != null) { addFieldError("upload", "该文件格式不支持上传!"); } }
filterTypes方法可以对上传进来的文件类型进行检测,如果不符合要求的话,就添加提示错误信息,因为使用了validate方法进行校验,所以如果校验失败的话会返回字符串“input”,所以需要在struts.xml中的结果里面配置一个input试图。
测试:
如果选择一个txt文本本件的话,可以上传,因为在
<param name="allowTypes">text/plain,img</param>中指定了text/plain的格式,但是如果选择一个.png格式的文件进行上传的话,就不能够进行。
点击提交之后:
这里使用了error.jsp中的
<s:fielderror>
<s:param>upload</s:param>
</s:fielderror>
进行输出提示信息。
2.拦截器实现文件过滤。
可以使用fileUpload拦截器进行拦截文件。
拦截器实现文件过滤的话,只需要在Action中配置该拦截器的引用即可,配置fileUpload时,可以为其指定两个参数:
allowedTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。
maximumSize:该参数指定允许上传的文件大小,单位是字符。
需要注意的是:
当文件过滤失败后,系统会自动的转入input逻辑视图,所以需要为该Action配置名为input的逻辑视图。此外,还必须显式地为该Action配置defaultStack的拦截器引用。
所以,如果想实现刚才自定义拦截器中的功能的话,可以在struts.xml中将action的配置修改为:
<action name="upload" class="hellostruts.upload"> <interceptor-ref name="fileUpload"> <param name="allowedTypes">text/plain,img</param> <param name="maximumSize">20000</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> <result>success.jsp</result> <result name="input">error.jsp</result> </action>
这样的话,就可以省略掉刚才所编写的自定义过滤文件的方法,但是能够达到相同的目的,可以看出这样使用拦截器实现文件过滤的话比较简单,但在某些情况下使用自定义方法进行过滤比较合适。
测试:
同样的,这里只支持text/plain的格式,如果想要上传其他格式的话,会在<fielderror>标签中显示如下内容:
如果上传的文件大小过大的话,会提示如下内容:
如果有什么错误的地方,希望大家能够指出。
相关文章推荐
- Java KeyNote
- 蓝桥杯 01字串
- JAVA路径中空格问题
- spring framework体系结构及内部各模块jar之间的maven依赖关系
- Struts2方便实用的内置校验器
- Spring 的Servlet拦截器匹配规则
- 剖析同步器(转载)
- springMVC注解
- Spring MVC 常用注解
- java2
- 重温Spring之旅6——基于XML配置方式进行AOP开发
- 蓝桥杯 基础练习01 Java实现
- spring data elasticsearch在集群新建了索引出现unsigned
- Spring4笔记1--Spring概述、IoC
- 彻底理解双重检验锁
- java中正则表达式的详解
- SSH网上商城--Struts2拦截器的应用
- Java反射之getInterfaces()方法
- 2017用java做一件事情
- SpringMVC原理图