基于struts2实现文件上传功能
??? ?在web开发应用中,文件上传是很多情形下必备的一项功能。本文详细介绍如何通过struts2实现一个简单的文件上传功能。
?
?首先了解几个术语:
????? MIME类型:设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。是描述消息内容类型的因特网标准。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。Tomcat的安装目录\conf\web.xml 中就定义了大量MIME类型。
????? 拦截器:是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。它是AOP思想的编程方式。提供一种机制使开发者能把相对独立的代码抽象出来,配置到Action前后执行。
???? 准备相应的jar包:commons-fileupload-1.2.1.jar;commons-io-1.4.jar;commons-logging-1.0.4.jar;freemarker-2.3.8.jar;ognl-2.6.11.jar;struts2-core-2.0.14.jar;xwork-2.0.7.jar。
???? 接下来编写一个Action名字叫做UploadAction,继承自ActionSupport虽然struts2的Action抛弃了request,response等Servlet API,但我们仍然可以通过ServletActionContext来得到相关Servlet对象,比如request,response,application,session等。
?
package org.common.action;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.Action;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("all")public class UploadAction extends ActionSupport {private File attach;private String attachContentType;private String attachFileName;public String upload() throws Exception {File saved = new File(ServletActionContext.getServletContext().getRealPath("uploads"), attachFileName);FileInputStream fis = null;FileOutputStream fos = null;try {saved.getParentFile().mkdirs();fis = new FileInputStream(attach);fos = new FileOutputStream(saved);byte[] bytes = new byte[1024];int len = 0;while ((len=fis.read(bytes))!=-1) {fos.write(bytes, 0, len);}} catch (Exception e) {e.printStackTrace();} finally {if (fis!=null) {fis.close();}if (fos!=null) {fos.close();}}return Action.SUCCESS;}public File getAttach() {return attach;}public void setAttach(File attach) {this.attach = attach;}public String getAttachContentType() {return attachContentType;}public void setAttachContentType(String attachContentType) {this.attachContentType = attachContentType;}public String getAttachFileName() {return attachFileName;}public void setAttachFileName(String attachFileName) {this.attachFileName = attachFileName;}}
?
?
???? ?配置struts.xml文件,注意package继承struts-default的相关配置,在使用拦截器的时候,在Action里面最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,不然会出错。
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts><constant name="struts.multipart.maxSize" value="50000000" /><constant name="struts.multipart.saveDir" value="/mytemp" /><package name="main" extends="struts-default"><!-- 所有的全局Result --> <global-results> <result name="login">/WEB-INF/jsp/login.jsp</result> </global-results><action name="struts" name="code"><body> <s:form enctype="multipart/form-data" action="struts!upload.action" method="post"> <s:file name="attach" label="图片附件"></s:file> <s:submit value="上传"></s:submit> <s:reset value="重置"></s:reset> </s:form> </body>
??
????? 上传成功的jsp页面:
?
<%@ page 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"><html> <head> <title>登录成功</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><!--<link rel="stylesheet" type="text/css" href="styles.css">--> </head> <body> <h1>恭喜你,<s:property value="username" />上传成功!</h1><br> </body></html>
???????? 总结一下:导入文件上传相关的两个组件commons-fileupload.jar和commons-io.jar,两者缺一不可;前台form表单设置enctype="multipart/form-data",file标签的name属性要与相关Action里的File属性名一致;后台定义上传Action,该Action可以定义文件的原始名称xxx与file的那么属性一致,struts会将原文件名设置到该属性上,此外还可以设置xxxContentType和xxxFileName属性,只要设置了这些都要提供相关的getter和setter方法供struts使用;根据需要使用fileUpload拦截器,从而可以限制上传文件大小和文件类型,注意上传文件大小需要在struts.multipart.maxSize属性要大于拦截器的maximumSize属性,否则maximum参数不起作用;显示使用了拦截器后,一定要将<interceptor-ref name="defaultStack"></interceptor-ref>引入;当想实现多个文件上传时,只需在Action中指定File[]或者List<File>类型的变量,并使用多个同名的<s:file />标签即可,如:
?private File[] attach;
?private String[] attachContentType;
?private String[] attachFileName;