Struts2上传文件要用到commons-fileupload和commons-io这两个组件
先看一个用Servlet而不用Struts2上传的例子吧
页面
<form action="/struts2/UploadServlet" method="post" enctype="multipart/form-data">
信息:<input type="text" name="info"/><br/>
文件:<input type="file" name="file"/><br/>
<input type="submit" name="submit"/>
</form>
Servlet代码
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("utf-8");
//创建工厂DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
//获得当前项目的Path(这里是当前项目下的/upload/fileupload的路径)
String path = request.getRealPath("/upload/fileupload");
//设置临时文件的存放路径
factory.setRepository(new File(path));
//设置临时文件的大小
factory.setSizeThreshold(1024*1024*2);
//创建ServletFileUpload对象,用工厂
ServletFileUpload upload = new ServletFileUpload(factory);
try {
//调用ServletFileUpload对象的parseRequest方法获得一个装了FileItem的List
List<FileItem> list = upload.parseRequest(request);
//每个FileItem里面封装了页面表单的信息(一个)
for(FileItem fileItem : list){
//ifFormField表示是平常的表单(非file类型的)
if(fileItem.isFormField()){
//获得表单名字,如<input type="text" name="info"/>这个里面的info
String name = fileItem.getFieldName();
//获得值value,并设置为UTF-8编码
String value = fileItem.getString("utf-8");
request.setAttribute(name, value);
}else{
//获得表单名字,如<input type="file" name="file"/>这个里面的info
String name = fileItem.getFieldName();
//获得名字,这个和非file表单不一样
String value = fileItem.getName();
//获得最后一个\的位置
int i = value.lastIndexOf("\\");
//在这个位置上加1,获得这个位置之后的String
value = value.substring(i+1);
request.setAttribute(name, value);
//组件已经封装好的write方法,当然也可以用request.getInputStream()来完成
fileItem.write(new File(path,value));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
//因为要传参数,所以转发
RequestDispatcher dispatcher = request.getRequestDispatcher("/upload/success.jsp");
dispatcher.forward(request, response);
}
}
用Struts2上传文件(多文件,一个文件和多个文是一样的)
先看页面,用了struts2的标签
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:form method="post" action="upload" enctype="multipart/form-data">
<s:textfield name="username" label="username"></s:textfield>
<s:password name="password" label="password"></s:password>
<s:file name="fileUpload" label="filePath"></s:file>
<s:file name="fileUpload" label="filePath"></s:file>
<s:file name="fileUpload" label="filePath"></s:file>
<s:file name="fileUpload" label="filePath"></s:file>
<s:submit value="Submit"></s:submit>
</s:form>
再看Action
public class FileUploadAction extends ActionSupport implements
ApplicationAware, SessionAware, ServletRequestAware,
ServletResponseAware {
private static final long serialVersionUID = 1L;
private Map application;
private Map session;
private HttpServletRequest request;
private HttpServletResponse response;
private String username;
private String password;
private List<File> fileUpload;
private List<String> fileUploadFileName;
private List<String> fileUploadContentType;
@Override
public String execute() throws Exception {
for(int i = 0;i<fileUpload.size();i++ ){
InputStream is = new FileInputStream(this.fileUpload.get(i));
String path = this.request.getRealPath("/upload/file");
OutputStream os = new FileOutputStream(new File(path,this.fileUploadFileName.get(i)));
byte[] b = new byte[1024*200];
int length = 0;
while((length = is.read(b))>0){
os.write(b, 0, length);
}
System.out.println("path = " + path);
System.out.println("fileName" + this.fileUploadFileName.get(i) + "contentType" +this.fileUploadContentType.get(i));
os.close();
is.close();
}
return Action.SUCCESS;
}
struts.xml配置文件
<action name="upload" class="com.langhua.action.FileUploadAction">
<result name="success">/upload/uploadsuccess.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
最后上传成功展示页面
username:${username}<br/>
password:${password}<br/>
fileName:${fileUploadFileName}<br/>
fileContentType:${fileUploadContentType}
使用Converter转换Action里面的fileUploadFileName,fileUploadContentType
public class UploadConverter extends StrutsTypeConverter {
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
List<String> list = new ArrayList<String>();
for(String value : values){
list.add(value);
}
return list;
}
@Override
public String convertToString(Map context, Object o) {
List<String> list = (List<String>) o;
StringBuffer sb = new StringBuffer();
for(String value : list){
sb.append(value).append(" ");
System.out.println(value);
}
return sb.toString();
}
}
再配置上
fileUploadFileName=com.langhua.converter.UploadConverter
fileUploadContentType=com.langhua.converter.UploadConverter
页面使用struts2的标签就转换了
fileName:<s:property value="fileUploadFileName"/><br/>
fileContentType:<s:property value="fileUploadContentType"/><br/>
还可在struts.xml里面配置
<constant name="struts.multipart.saveDir" value="c:/temp"></constant>
<constant name="struts.multipart.maxSize" value="209715200"></constant>
设置上传时temp文件放的位置和最大文件的大小
还有其它的可以配置,他们都在org.apache.struts2.default.properties里面有的
比如说改连结的后缀名,编码,用的上传文件的类库
struts.i18n.encoding=UTF-8
struts.multipart.parser=jakarta
struts.action.extension=action
Struts2下载文件
<action name="download" class="com.langhua.action.DownloadAction" method="downloadFile">
<!--type 为 stream 应用 StreamResult 处理-->
<result name="success" type="stream">
<!--默认为 text/plain-->
<!-- <param name="contentType">image/pjpeg</param> -->
<!-- 默认为 inline(在线打开),设置为 attachment 将会告诉浏览器下载该文件,filename 指定下载文
件保有存时的文件名,若未指定将会是以浏览的页面名作为文件名,如以 download.action 作为文件名,
这里使用的是动态文件名,${fileName}, 它将通过 Action 的 getFileName() 获得文件名 -->
<param name="contentDisposition">attachment;filename="${filename}"</param>
<!-- 默认就是 inputStream,它将会指示 StreamResult 通过 inputName 属性值的 getter 方法,
比如这里就是 getInputStream() 来获取下载文件的内容,意味着你的 Action 要有这个方法 -->
<param name="inputName">inputStram</param>
<param name="bufferSize">4096</param><!-- 输出时缓冲区的大小 -->
</result>
</action>
type为stream的参数来自这个类
package org.apache.struts2.dispatcher;
public class StreamResult extends StrutsResultSupport {
protected String contentType = "text/plain";
protected String contentLength;
protected String contentDisposition = "inline";
protected String inputName = "inputStream";
protected InputStream inputStream;
protected int bufferSize = 1024;
}