Struts2使用开源项目Apache Jakarta Commons FileUpload和内建的FileUploadInterceptor拦截器实现文件上传,所需的jar包如下:
commons-logging-1.1.jar freemarker-2.3.8.jar ognl-2.6.11.jar struts2-core-2.0.6.jar xwork-2.0.1.jar commons-io-1.3.1.jar commons-fileupload-1.2.jar
★ 文件上传页面 fileupload.jsp
< %@ page language ="java" contentType ="text/html; charset=GBK" %> < %@ taglib prefix ="s" uri ="/struts-tags" %> < html > < head > < head > < body > < s:form action = "fileUpload" method = "post" enctype = "multipart/form-data" > < s:file name = "doc" label = "File" /> < s:submit /> < s:form > < body > < html>
这里需要注意的是,form的enctype属性必须设置为multipart/form-data。
★ 处理文件上传 FileUploadAction.java
package fileupload; import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import javax.servlet.ServletContext; import org.apache.commons.io.FileUtils; import org.apache.struts2.util.ServletContextAware; import com.opensymphony.xwork2.ActionSupport; public class FileUploadAction extends ActionSupport implements ServletContextAware { private static final long serialVersionUID = -5016873153441103539L; private File doc; private String fileName; private String contentType; private ServletContext context; public void setDoc(File file) { this .doc = file; } public void setDocFileName(String fileName) { this .fileName = fileName; } public void setDocContentType(String contentType) { this .contentType = contentType; } public void setServletContext(ServletContext context) { this .context = context; } public String execute() throws Exception { String targetDirectory = context.getRealPath( "/upload" ); File target = new File(targetDirectory, filename); FileUtils.copyFile(doc, target); return SUCCESS; } }
在fileupload.jsp中,只有doc一个字段,而FileUploadAction.java中,却有三个字段,Struts2怎么通过页面的一个字段设置Action里的三个字段呢?没错,这就是FileUploadInterceptor的功劳了!你所要做的只是按照一定的样式命名这三个字段的set方法,而字段名可以任意命名。第一个File类型的字段的set方法还是以常规的方式命名,另两个String类型的字段的set方法必须分别以“File字段的set方法名+FileName”和“File字段的set方法名+ContentType”来命名。
★ 配置文件 struts.xml
<? 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 > < package name = "fileupload" namespace = "/fileupload" extends = "struts-default" > < action name = "fileUpload" class = "fileupload.FileUploadAction" > < result > /fileupload/upload_success.jsp </ result > </ action > </ package > </ struts >
★ 配置文件 web.xml
<? xml version ="1.0" encoding ="UTF-8" ?> < web-app version ="2.4" xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > < filter > < filter-name > struts-cleanup </ filter-name > < filter-class > org.apache.struts2.dispatcher.ActionContextCleanUp </ filter-class > </ filter > < filter > < filter-name > struts2 </ filter-name > < filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class > </ filter > < filter-mapping > < filter-name > struts-cleanup </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping > < filter-mapping > < filter-name > struts2 </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping > </ web-app >
struts-cleanup的作用
就是说,一般情况下,如果你要用SiteMesh或者 其他 过滤器,一般是放在FilterDispatcher或者是现在的StrutsPrepareAndExecuteFilter之前。在调用完所有过滤器的doFilter方法后,核心过滤器FilterDispatcher或者StrutsPrepareAndExecuteFilter会清空ActionContext,如果其他过滤器要一直使用value stack等struts的特性时,如果不用ActionContextCleanUp的话,便得不到想要的值。 ActionContextCleanUp的作用就是上面用粗体标注出来的那一句。它会在doFilter方法里设置一个计数器counter的初始值为1,有了这个值,后续的核心过滤器就不会清空ActionContext,而是由之前的过滤器也就是ActionContextCleanUp来清空ActionContext。
处理中文问题
利用struts2做文件上传,中文处理需要处理两个地方:
(1)struts.xml设置<constant name="struts.i18n.encoding" value="GBK"/>,或者struts.properties文件设置struts.i18n.encoding=GBK
(2)上传文件的页面编码设置成GBK,如:<%@ page language="java" pageEncoding="GBK"%>