轉載至:http://blog.csdn.net/hanxiaoshuang123/article/details/7342091css
Struts2多個文件上傳
多個文件上傳分爲List集合和數組,下面咱們着重介紹一下list集合的上傳。都大同小異。
一 介紹
1. 在struts2文件上傳的時候要先導入struts2的幾個包,在struts2.3.1.2中,導入的包如圖所視:
從圖上能夠看出其中文件上傳所須要的是包爲commons-fileupload-1.2.2.jar和commons-io-2.0.1.jar包。
2. Struts2文件上傳並未提供本身的請求解析器,也就是說,struts2不會本身去處理multipart/form-data的請求,它須要調用其餘的請求解析器,將http請求中的表單域解析出來。但struts2在原有的上傳解析器繼承上作了進一步封裝,更進一步簡化了文件上傳。
3. Struts2默認使用的是Jakarta和Connon-FileUpload的文件上傳框架,所以,若是須要使用struts2的文件上傳功能,則須要在Web應用導入上面我所說的幾個包
4. Struts2的文件上傳支持在原有的問上傳項目上作了進一步封裝,簡化了文件上傳代碼實現,取消了不一樣上傳項目上編程差別。
二 實例
1. 首先咱們來了解一下表單屬性enctype屬性的意義
表單的enctype屬性指定的是表單數據的編碼方式,該屬性呢有3個值
(1) application/x-www-form-urlencoded,這是默認的編碼方式,它只能處理表單域裏的value屬性,採用這種編碼方式的表單會將表單域的值處理成URL編碼方式。
(2) multipart/form-data,採用這種編碼方式會以二進制流的方式來處理表單數據 ,這種編碼方式會把文件域指定文件的內容也封裝到請求參數裏。
(3) text/plain,這種編碼方式當表單的action屬性爲mailto:URL的形式是比較方便,這種方式主要適用於直接經過表單發送郵件的方式。
從以上的介紹能夠看出爲何文件上傳要用到的是multipart/form-data屬性了吧!上傳的文件會在底層封裝,並經過二進制流讀取。
2. 下面咱們來寫這樣一個界面來實現多文件的上傳:
所用的html代碼爲:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'tagUpload.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->html
</head>java
<body>
<h3>
多個文件上傳實例
</h3>
<s:form action="/csdn/uploadList.action" enctype="multipart/form-data"
method="post">
<s:textfield label="上傳名稱" name="name"></s:textfield>
<s:file label="上傳文件" name="upload"></s:file>
<s:file label="上傳文件" name="upload"></s:file>
<s:file label="上傳文件" name="upload"></s:file>
<s:submit value="上傳" />
</s:form>
</body>
</html>apache
在這裏要注意的是要引入標籤:
<%@ taglib uri="/struts-tags" prefix="s"%>編程
上面的頁面只是一個普通的html頁面,沒有任何的動態部分,當該頁面提交請求的時候發送到/csdn/uploadList.action,這是一個struts2的action。
Struts2的Action無需負責處理HttpServletRequest請求,由於struts2的Action已經與servletAPI完全分離了,struts2框架負責解析httpServletRequest請求的參數,包括文件域,strtus2使用File類型來封裝文件域。
3.下面是處理Action的代碼:數組
package cn.csdn.hr.up.action;app
import java.io.File;
import java.io.IOException;
import java.util.List;框架
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;jsp
import com.opensymphony.xwork2.ActionSupport;post
public class TagUploadListAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private String name;
// 上傳多個文件的集合文本
private List<File> upload;
// /多個上傳文件的類型集合
private List<String> uploadContextType;
// 多個上傳文件的文件名集合
private List<String> uploadFileName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<File> getUpload() {
return upload;
}
public void setUpload(List<File> upload) {
this.upload = upload;
}
public List<String> getUploadContextType() {
return uploadContextType;
}
public void setUploadContextType(List<String> uploadContextType) {
this.uploadContextType = uploadContextType;
}
public List<String> getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(List<String> uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String execute() {
// 把上傳的文件放到指定的路徑下
String path = ServletActionContext.getServletContext().getRealPath(
"/WEB-INF/uploadList");
// 寫到指定的路徑中
File file = new File(path);
// 若是指定的路徑沒有就建立
if (!file.exists()) {
file.mkdirs();
}
// 把獲得的文件的集合經過循環的方式讀取並放在指定的路徑下
for (int i = 0; i < upload.size(); i++) {
try {
//list集合經過get(i)的方式來獲取索引
FileUtils.copyFile(upload.get(i), new File(file, uploadFileName.get(i)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return SUCCESS;
}
}
經過以上的Action咱們能夠看出Action還包括了兩個屬性,uploadFileName,uploadContextType, 這兩個屬性分別用來封裝上傳我文件的文件名,上傳文件的文件類型,這兩個屬性體現了struts設計的靈巧、簡化之處,Action類直接經過File類型屬性直接封裝了上傳文件的內容,但這個File屬性沒法獲取上傳文件的文件名和文件類型,因此struts2直接將包含的上傳文件名和文件類型的信息封裝到uploadFileName,uploadContextType屬性中,能夠認爲:若是表單中包含一個name屬性爲xxx的文件域,則對應的Action須要使用3個屬性來封裝該文件域的信息:
(1) 類型爲File的xxx屬性封裝了該文件域對應的文件內容
(2) 類型爲String的xxxFileName屬性封裝了該案文件域對應的文件的文件類型
(3) 類型爲String的xxxContextType屬性封裝了該文件域對應的文件的類型
經過上嗎的三個屬性能夠簡單的實現上傳文件的文件名、文件類型和文件內容
3. 配置action的strtus.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="file" extends="struts-default" namespace="/csdn">
<action name="uploadList" class="cn.csdn.hr.up.action.TagUploadListAction">
<result>../success.jsp</result>
<result name="input">../tagUpload.jsp</result>
</action>
</package>
</struts>
4. 設置上傳的文件的大小和類型
就是在struts.xml中用攔截器來設置
<action name="uploadList" class="cn.csdn.hr.up.action.TagUploadListAction">
<result>../success.jsp</result>
<result name="input">../tagUpload.jsp</result>
<!-- 經過攔截器來限制上傳圖片的類型和大小 -->
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/x-png,image/gif</param>
<param name="maximumSize">200</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
顯示的錯誤提示信息的標籤爲:
<s:fielderror></s:fielderror>
以上的多個文件上傳是List集合的,數組的也不過如此,要改變的地方爲Action接收的時候類型的不一樣和讀取的時候循環不一樣,下面的數組的例子爲:
// 獲得上傳文件的名稱必定與name值一直
private File upload[];
// 上傳文件的類型 ContentType
private String uploadContentType[];
// 上傳文件的名稱
private String uploadFileName[];
public File[] getUpload() {
return upload;
}
public void setUpload(File[] upload) {
this.upload = upload;
}
public String[] getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String[] uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String[] getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String[] uploadFileName) {
this.uploadFileName = uploadFileName;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String uploads() {
String path = ServletActionContext.getServletContext().getRealPath(
"/upload");
// 寫到指定路徑 File file = new File(path); //判斷指定的路徑下是否有uplaod,若是沒有,自動建立 if (!file.exists()) { file.mkdirs(); } try { for(int i = 0;i<upload.length;i++){ FileUtils.copyFile(upload[i], new File(file, uploadFileName[i])); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return SUCCESS; }