多个文件上传分为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代码为:
- <%@pagelanguage="java"import="java.util.*"pageEncoding="utf-8"%>
- <%@tagliburi="/struts-tags"prefix="s"%>
- <%
- Stringpath=request.getContextPath();
- StringbasePath=request.getScheme()+"://"
- +request.getServerName()+":"+request.getServerPort()
- +path+"/";
- %>
- <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
- <html>
- <head>
- <basehref="<%=basePath%>">
- <title>MyJSP'tagUpload.jsp'startingpage</title>
- <metahttp-equiv="pragma"content="no-cache">
- <metahttp-equiv="cache-control"content="no-cache">
- <metahttp-equiv="expires"content="0">
- <metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
- <metahttp-equiv="description"content="Thisismypage">
- <!--
- <linkrel="stylesheet"type="text/css"href="styles.css">
- -->
- </head>
- <body>
- <h3>多个文件上传实例</h3>
- <s:formaction="/csdn/uploadList.action"enctype="multipart/form-data"method="post">
- <s:textfieldlabel="上传名称"name="name"></s:textfield>
- <s:filelabel="上传文件"name="upload"></s:file>
- <s:filelabel="上传文件"name="upload"></s:file>
- <s:filelabel="上传文件"name="upload"></s:file>
- <s:submitvalue="上传"/>
- </s:form>
- </body>
- </html>
在这里要注意的是要引入标签:
- <%@tagliburi="/struts-tags"prefix="s"%>
上面的页面只是一个普通的html页面,没有任何的动态部分,当该页面提交请求的时候发送到/csdn/uploadList.action,这是一个struts2的action。
Struts2的Action无需负责处理HttpServletRequest请求,因为struts2的Action已经与servletAPI彻底分离了,struts2框架负责解析httpServletRequest请求的参数,包括文件域,strtus2使用File类型来封装文件域。
3.下面是处理Action的代码:
- packagecn.csdn.hr.up.action;
- importjava.io.File;
- importjava.io.IOException;
- importjava.util.List;
- importorg.apache.commons.io.FileUtils;
- importorg.apache.struts2.ServletActionContext;
- importcom.opensymphony.xwork2.ActionSupport;
- publicclassTagUploadListActionextendsActionSupport{
- privatestaticfinallongserialVersionUID=1L;
- privateStringname;
- //上传多个文件的集合文本
- privateList<File>upload;
- ///多个上传文件的类型集合
- privateList<String>uploadContextType;
- //多个上传文件的文件名集合
- privateList<String>uploadFileName;
- publicStringgetName(){
- returnname;
- }
- publicvoidsetName(Stringname){
- this.name=name;
- }
- publicList<File>getUpload(){
- returnupload;
- }
- publicvoidsetUpload(List<File>upload){
- this.upload=upload;
- }
- publicList<String>getUploadContextType(){
- returnuploadContextType;
- }
- publicvoidsetUploadContextType(List<String>uploadContextType){
- this.uploadContextType=uploadContextType;
- }
- publicList<String>getUploadFileName(){
- returnuploadFileName;
- }
- publicvoidsetUploadFileName(List<String>uploadFileName){
- this.uploadFileName=uploadFileName;
- }
- publicStringexecute(){
- //把上传的文件放到指定的路径下
- Stringpath=ServletActionContext.getServletContext().getRealPath(
- "/WEB-INF/uploadList");
- //写到指定的路径中
- Filefile=newFile(path);
- //如果指定的路径没有就创建
- if(!file.exists()){
- file.mkdirs();
- }
- //把得到的文件的集合通过循环的方式读取并放在指定的路径下
- for(inti=0;i<upload.size();i++){
- try{
- //list集合通过get(i)的方式来获取索引
- FileUtils.copyFile(upload.get(i),newFile(file,uploadFileName.get(i)));
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- }
- returnSUCCESS;
- }
- }
通过以上的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
- <?xmlversion="1.0"encoding="GBK"?>
- <!DOCTYPEstrutsPUBLIC
- "-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.3//EN"
- "http://struts.apache.org/dtds/struts-2.3.dtd">
- <struts>
- <packagename="file"extends="struts-default"namespace="/csdn">
- <actionname="uploadList"class="cn.csdn.hr.up.action.TagUploadListAction">
- <result>../success.jsp</result>
- <resultname="input">../tagUpload.jsp</result>
- </action>
- </package>
- </struts>
4. 设置上传的文件的大小和类型
就是在struts.xml中用拦截器来设置
- <actionname="uploadList"class="cn.csdn.hr.up.action.TagUploadListAction">
- <result>../success.jsp</result>
- <resultname="input">../tagUpload.jsp</result>
- <!--通过拦截器来限制上传图片的类型和大小-->
- <interceptor-refname="fileUpload">
- <paramname="allowedTypes">image/bmp,image/x-png,image/gif</param>
- <paramname="maximumSize">200</param>
- </interceptor-ref>
- <interceptor-refname="defaultStack"></interceptor-ref>
- </action>
显示的错误提示信息的标签为:
<s:fielderror></s:fielderror>
以上的多个文件上传是List集合的,数组的也不过如此,要改变的地方为Action接收的时候类型的不同和读取的时候循环不同,下面的数组的例子为:
- //得到上传文件的名称一定与name值一直
- privateFileupload[];
- //上传文件的类型ContentType
- privateStringuploadContentType[];
- //上传文件的名称
- privateStringuploadFileName[];
- publicFile[]getUpload(){
- returnupload;
- }
- publicvoidsetUpload(File[]upload){
- this.upload=upload;
- }
- publicString[]getUploadContentType(){
- returnuploadContentType;
- }
- publicvoidsetUploadContentType(String[]uploadContentType){
- this.uploadContentType=uploadContentType;
- }
- publicString[]getUploadFileName(){
- returnuploadFileName;
- }
- publicvoidsetUploadFileName(String[]uploadFileName){
- this.uploadFileName=uploadFileName;
- }
- publicstaticlonggetSerialversionuid(){
- returnserialVersionUID;
- }
- publicStringuploads(){
- Stringpath=ServletActionContext.getServletContext().getRealPath(
- "/upload");
- //写到指定路径
- Filefile=newFile(path);
- //判断指定的路径下是否有uplaod,如果没有,自动创建
- if(!file.exists()){
- file.mkdirs();
- }
- try{
- for(inti=0;i<upload.length;i++){
- FileUtils.copyFile(upload[i],newFile(file,uploadFileName[i]));
- }
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- returnSUCCESS;
- }