struts2多文件上传进度条(附源码)

package controller;

import java.io.IOException;

import org.apache.struts2.ServletActionContext;

import tools.State;

public class GetState {

	public String execute() throws IOException {
		// 从session中取得名称为uploadState的State对象
		// 这个对象里面存储的信息是当前上传的基本信息
		State tempState = (State) ServletActionContext.getRequest()
				.getSession().getAttribute("uploadState");
		// 调试:在控制台输出当前取得状态字符串的内容
		System.out.println("取得的XML文件的内容为:" + tempState.getStateString());
		// 设置编码为utf-8
		ServletActionContext.getResponse().setCharacterEncoding("utf-8");
		// 设置响应的格式为XML
		ServletActionContext.getResponse().setContentType("text/xml");
		// 用out对象输出xml代码头
		ServletActionContext.getResponse().getWriter().print(
				"<?xml version='1.0' encoding='" + "utf-8" + "' ?>");
		// 用out对象输出xml代码体
		ServletActionContext.getResponse().getWriter().print(
				tempState.getStateString());
		return null;
	}
}
 
package controller;

import java.io.IOException;

import upload.FileUploadTools;

import com.opensymphony.xwork2.ActionSupport;

public class Register extends ActionSupport {
	// 上传工具的引用
	private FileUploadTools fileUploadTools = new FileUploadTools();

	public FileUploadTools getFileUploadTools() {
		return fileUploadTools;
	}

	public void setFileUploadTools(FileUploadTools fileUploadTools) {
		this.fileUploadTools = fileUploadTools;
	}

	@Override
	public void validate() {

	}

	public String execute() throws IOException {
		// 调用beginUpload方法开始上传
		fileUploadTools.beginUpload();

		return "register";
	}

}
 
package tools;

import java.util.ArrayList;
import java.util.List;

public class State {

	private static List state = new ArrayList();

	// 从State状态类中取得状态的字符串
	// 用字符串的形式拼成XML文件内容
	public synchronized String getStateString() {
		String returnString = "<info><uploadByte>";
		returnString = returnString + state.get(0) + "</uploadByte>";
		returnString = returnString + "<fileSizeByte>" + state.get(1)
				+ "</fileSizeByte>";
		returnString = returnString + "<fileIndex>" + state.get(2)
				+ "</fileIndex>";
		returnString = returnString + "<percent>" + state.get(3)
				+ "</percent></info>";
		return returnString;
	}

	// 设置状态文本中的信息
	// 暂时放到List中,后期将List中的数据取出来拼成XML文本内容
	public synchronized void setStateString(String uploadByte,
			String fileSizeByte, String fileIndex) {
		state.add(0, uploadByte);
		state.add(1, fileSizeByte);
		state.add(2, fileIndex);
		// 生成当前上传进度的公式
		if ((Long.valueOf(uploadByte) * 100 / Long.valueOf(fileSizeByte) < 100)) {
			state.add(3, Long.valueOf(uploadByte) * 100
					/ Long.valueOf(fileSizeByte));
		}
	}
}
 
package upload;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.ProgressListener;

import tools.State;

public class FileUploadListener implements ProgressListener {
	// 声明一个HttpSession
	// 目的是把State对象入到这个HttpSession中
	private HttpSession session;

	// 构造方法
	// 参数request来源于GhyJakartaMultiPartRequest.java类中的75行
	public FileUploadListener(HttpServletRequest request) {
		super();
		session = request.getSession();
	}

	public void update(long uploadByte, long fileSizeByte, int fileIndex) {
		if (fileSizeByte == -1) {
			// 如果上传的大小为-1则上传已经完成
			System.out.println("完成了");
		} else {
			if (session.getAttribute("uploadState") == null) {
				// 每次执行时从session中取出uploadState对象
				// 如果为空就new一个State对象并设置里面的XML状态文本内容
				// 并且再次放入session中
				State state = new State();
				state.setStateString("" + uploadByte, "" + fileSizeByte, ""
						+ (fileIndex - 1));
				session.setAttribute("uploadState", state);
			} else {
				// 如果session中有uploadState对象
				// 就取出来,然后设置里面的XML状态文本内容
				// 并且再次放入session中
				State state = (State) session.getAttribute("uploadState");
				state.setStateString("" + uploadByte, "" + fileSizeByte, ""
						+ (fileIndex - 1));
				session.setAttribute("uploadState", state);
			}
		}

	}
}
package upload;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

public class FileUploadTools {

	private String username;

	private File uploadFile[];// 允许上传多个文件,所以是数组类型

	private String uploadFileFileName[];// 允许上传多个文件,所以文件名是数组类型

	private String uploadFileContentType[];// 允许上传多个文件,文件的类型是数组类型

	public String[] getUploadFileContentType() {
		return uploadFileContentType;
	}

	public void setUploadFileContentType(String[] uploadFileContentType) {
		this.uploadFileContentType = uploadFileContentType;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public File[] getUploadFile() {
		return uploadFile;
	}

	public void setUploadFile(File[] uploadFile) {
		this.uploadFile = uploadFile;
	}

	public String[] getUploadFileFileName() {
		return uploadFileFileName;
	}

	public void setUploadFileFileName(String[] uploadFileFileName) {
		this.uploadFileFileName = uploadFileFileName;
	}

	public String beginUpload() throws IOException {
		// 开始上传
		System.out.println("username的值是:" + username);
		// 取得上传的目录
		String targetDirectory = ServletActionContext.getRequest().getRealPath(
				"/upload");
		// 循环取得每个文件,然后依次上传
		for (int i = 0; i < uploadFile.length; i++) {

			File target = new File(targetDirectory, new SimpleDateFormat(
					"yyyy_MM_dd_HH_mm_ss").format(new Date()).toString()
					+ System.nanoTime() + uploadFileFileName[i]);

			FileUtils.copyFile(uploadFile[i], target);
		}

		return "register";
	}

}
 
package upload;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;

import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;

/**
 * Multipart form data request adapter for Jakarta Commons Fileupload package.
 */
public class GhyJakartaMultiPartRequest implements MultiPartRequest {

	static final Logger LOG = LoggerFactory.getLogger(MultiPartRequest.class);

	// maps parameter name -> List of FileItem objects
	protected Map<String, List<FileItem>> files = new HashMap<String, List<FileItem>>();

	// maps parameter name -> List of param values
	protected Map<String, List<String>> params = new HashMap<String, List<String>>();

	// any errors while processing this request
	protected List<String> errors = new ArrayList<String>();

	protected long maxSize;

	@Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)
	public void setMaxSize(String maxSize) {
		this.maxSize = Long.parseLong(maxSize);
	}

	/**
	 * Creates a new request wrapper to handle multi-part data using methods
	 * adapted from Jason Pell's multipart classes (see class description).
	 * 
	 * @param saveDir
	 *            the directory to save off the file
	 * @param request
	 *            the request containing the multipart
	 * @throws java.io.IOException
	 *             is thrown if encoding fails.
	 */
	public void parse(HttpServletRequest request, String saveDir)
			throws IOException {
		try {
			processUpload(request, saveDir);
		} catch (FileUploadException e) {
			LOG.warn("Unable to parse request", e);
			errors.add(e.getMessage());
		}
	}

	private void processUpload(HttpServletRequest request, String saveDir)
			throws FileUploadException, UnsupportedEncodingException {
		for (FileItem item : parseRequest(request, saveDir)) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("Found item " + item.getFieldName());
			}
			if (item.isFormField()) {
				processNormalFormField(item, request.getCharacterEncoding());
			} else {
				processFileField(item);
			}
		}
	}

	private void processFileField(FileItem item) {
		LOG.debug("Item is a file upload");

		// Skip file uploads that don't have a file name - meaning that no file
		// was selected.
		if (item.getName() == null || item.getName().trim().length() < 1) {
			LOG.debug("No file has been uploaded for the field: "
					+ item.getFieldName());
			return;
		}

		List<FileItem> values;
		if (files.get(item.getFieldName()) != null) {
			values = files.get(item.getFieldName());
		} else {
			values = new ArrayList<FileItem>();
		}

		values.add(item);
		files.put(item.getFieldName(), values);
	}

	private void processNormalFormField(FileItem item, String charset)
			throws UnsupportedEncodingException {
		LOG.debug("Item is a normal form field");
		List<String> values;
		if (params.get(item.getFieldName()) != null) {
			values = params.get(item.getFieldName());
		} else {
			values = new ArrayList<String>();
		}

		// note: see http://jira.opensymphony.com/browse/WW-633
		// basically, in some cases the charset may be null, so
		// we're just going to try to "other" method (no idea if this
		// will work)
		if (charset != null) {
			values.add(item.getString(charset));
		} else {
			values.add(item.getString());
		}
		params.put(item.getFieldName(), values);
	}

	// 高洪岩改动parseRequest方法
	private List<FileItem> parseRequest(HttpServletRequest servletRequest,
			String saveDir) throws FileUploadException {
		DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
		ServletFileUpload upload = new ServletFileUpload(fac);
		upload.setProgressListener(new FileUploadListener(servletRequest));// :)
		upload.setSizeMax(maxSize);
		return upload.parseRequest(createRequestContext(servletRequest));
	}

	private DiskFileItemFactory createDiskFileItemFactory(String saveDir) {
		DiskFileItemFactory fac = new DiskFileItemFactory();
		// Make sure that the data is written to file
		fac.setSizeThreshold(0);
		if (saveDir != null) {
			fac.setRepository(new File(saveDir));
		}
		return fac;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.apache.struts2.dispatcher.multipart.MultiPartRequest#
	 * getFileParameterNames()
	 */
	public Enumeration<String> getFileParameterNames() {
		return Collections.enumeration(files.keySet());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getContentType
	 * (java.lang.String)
	 */
	public String[] getContentType(String fieldName) {
		List<FileItem> items = files.get(fieldName);

		if (items == null) {
			return null;
		}

		List<String> contentTypes = new ArrayList<String>(items.size());
		for (FileItem fileItem : items) {
			contentTypes.add(fileItem.getContentType());
		}

		return contentTypes.toArray(new String[contentTypes.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFile(java
	 * .lang.String)
	 */
	public File[] getFile(String fieldName) {
		List<FileItem> items = files.get(fieldName);

		if (items == null) {
			return null;
		}

		List<File> fileList = new ArrayList<File>(items.size());
		for (FileItem fileItem : items) {
			fileList.add(((DiskFileItem) fileItem).getStoreLocation());
		}

		return fileList.toArray(new File[fileList.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFileNames
	 * (java.lang.String)
	 */
	public String[] getFileNames(String fieldName) {
		List<FileItem> items = files.get(fieldName);

		if (items == null) {
			return null;
		}

		List<String> fileNames = new ArrayList<String>(items.size());
		for (FileItem fileItem : items) {
			fileNames.add(getCanonicalName(fileItem.getName()));
		}

		return fileNames.toArray(new String[fileNames.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFilesystemName
	 * (java.lang.String)
	 */
	public String[] getFilesystemName(String fieldName) {
		List<FileItem> items = files.get(fieldName);

		if (items == null) {
			return null;
		}

		List<String> fileNames = new ArrayList<String>(items.size());
		for (FileItem fileItem : items) {
			fileNames.add(((DiskFileItem) fileItem).getStoreLocation()
					.getName());
		}

		return fileNames.toArray(new String[fileNames.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameter
	 * (java.lang.String)
	 */
	public String getParameter(String name) {
		List<String> v = params.get(name);
		if (v != null && v.size() > 0) {
			return v.get(0);
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameterNames
	 * ()
	 */
	public Enumeration<String> getParameterNames() {
		return Collections.enumeration(params.keySet());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameterValues
	 * (java.lang.String)
	 */
	public String[] getParameterValues(String name) {
		List<String> v = params.get(name);
		if (v != null && v.size() > 0) {
			return v.toArray(new String[v.size()]);
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors()
	 */
	public List getErrors() {
		return errors;
	}

	/**
	 * Returns the canonical name of the given file.
	 * 
	 * @param filename
	 *            the given file
	 * @return the canonical name of the given file
	 */
	private String getCanonicalName(String filename) {
		int forwardSlash = filename.lastIndexOf("/");
		int backwardSlash = filename.lastIndexOf("\\");
		if (forwardSlash != -1 && forwardSlash > backwardSlash) {
			filename = filename.substring(forwardSlash + 1, filename.length());
		} else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {
			filename = filename.substring(backwardSlash + 1, filename.length());
		}

		return filename;
	}

	/**
	 * Creates a RequestContext needed by Jakarta Commons Upload.
	 * 
	 * @param req
	 *            the request.
	 * @return a new request context.
	 */
	private RequestContext createRequestContext(final HttpServletRequest req) {
		return new RequestContext() {
			public String getCharacterEncoding() {
				return req.getCharacterEncoding();
			}

			public String getContentType() {
				return req.getContentType();
			}

			public int getContentLength() {
				return req.getContentLength();
			}

			public InputStream getInputStream() throws IOException {
				InputStream in = req.getInputStream();
				if (in == null) {
					throw new IOException("Missing content in the request");
				}
				return req.getInputStream();
			}
		};
	}

}
 
<?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="struts3.1" extends="struts-default">
		<action name="register" class="controller.Register">
			<result name="register">/showregister.jsp</result>
			<result name="input">/register.jsp</result>
		</action>

		<action name="getState" class="controller.GetState"></action>

	</package>

	<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="GhyJakartaMultiPartRequestRef"
		class="upload.GhyJakartaMultiPartRequest" scope="default" />

	<constant name="struts.multipart.handler" value="GhyJakartaMultiPartRequestRef" />

	<constant name="struts.ui.theme" value="simple"></constant>
</struts>
 
struts.multipart.maxSize=2048000000
struts.multipart.saveDir=/tempUploadFile
 
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<%@ page isELIgnored="false" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>多文件上传实例</title>
        <style type="text/css">
        <!--
        
        body, td, th {
            font-size: 9pt;
        }
        -->
        </style>
        <script src="jquery/jquery-1.3.2.js">
        </script>
        <script type="text/javascript">
            
            function showprocessorBar(){
                //上传时显示进度条
                //该方法被submitForm()调用
                $.get("getState.action?timestamp=" + new Date().getTime(), function(date){
                    processorBarCallBack();
                });
            }
            
            function processorBarCallBack(){
                //showprocessorBar方法的回调
                setTimeout("reshowprocessorBar()", 1000);
            }
            
            function reshowprocessorBar(){//定时调用这个显示进度的function
                $.get("getState.action?timestamp=" + new Date().getTime(), function(data){
                    reprocessorBarCallBack(data);
                }, 'xml');
            }
            
            function reprocessorBarCallBack(returnXMLParam){//回调一下:)
                var returnXML = returnXMLParam;
                var percene = $(returnXML).find('percent').text()
                var showText = "进度是:" + $(returnXML).find('percent').text();
                showText = showText + "\n当前上传文件大小为:" + $(returnXML).find ('uploadByte').text();
                showText = showText + "\n上传文件总大小为:" + $(returnXML).find ('fileSizeByte').text();
                showText = showText + "\n当前上传文件为第:" + $(returnXML).find ('fileIndex').text() + "个";
                
                //清空id为progr的DIV里面的数据,然后再添加
                $('#progr').empty();
                $('#progr').text(showText);
                
                var jidutiao = $('#jidutiao');
                
                //设置进度条的长度
                if ((100 - parseInt(percene)) > 0) {
                    $('#jidutiao').css('width', 100 - parseInt(percene) + "%");
                }
                else {
                    $('#jidutiao').css('width', "100%");
                    
                }
                
                setTimeout("reshowprocessorBar()", 1000);
            }
            
            
            
            ////////////////////////////////
            
            var a = 0;
            
            function file_change(){
                //当文本域中的值改变时触发此方法
                var postfix = this.value.substring(this.value.lastIndexOf(".") + 1).toUpperCase();
                //判断扩展是否合法
                if (postfix == "JPG" || postfix == "GIF" || postfix == "PNG" || postfix == "BMP" ||
                postfix == "RAR" ||
                postfix == "ZIP" ||
                postfix == "TXT" ||
                postfix == "GHO" ||
                postfix == "PDF") {
                }
                else {
                    //如果不合法就删除相应的File表单及br标签
                    alert("您上传的文件类型不被支持,本系统只支持JPG,GIF,PNG,BMP,RAR,ZIP,TXT文件!");
                    var testtest = $(this).attr('id');
                    testtest = '#' + testtest;
                    var sub_file = $(testtest);
                    
                    var next_a_ele = sub_file.next();//取得a标记
                    
                    var br1_ele = $(next_a_ele).next();//取得回车
                    
                    
                    var br2_ele = $(br1_ele).next();//取得回车
                    
                    
                    $(br2_ele).remove();//删除回车
                    
                    $(br1_ele).remove();//删除回车
                    
                    
                    $(next_a_ele).remove();//删除a标签
                    
                    $(sub_file).remove();
//删除文本域,因为上传的文件类型出错,要删除动态创建的File表单
                    
                    
                    return;
                    
                }
                
            }
            
            function remove_file(){//删除File表单域的方法
                //删除表单
                var testtest = $(this).val();
                testtest = '#' + testtest;
                var sub_file = $(testtest);
                
                var next_a_ele = sub_file.next();//取得a标记
                
                var br1_ele = $(next_a_ele).next();//取得回车
                
                
                var br2_ele = $(br1_ele).next();//取得回车
                
                
                $(br2_ele).remove();//删除回车
                
                $(br1_ele).remove();//删除回车
                
                
                $(next_a_ele).remove();//删除a标签
                
                $(sub_file).remove();//删除File标记
                
            }
            
            function f(){
//方法名为f的主要作用是不允许在File表单域中手动输入文件名,必须单击“浏览”按钮
                return false;
            }
            
            function insertFile(){
                //新建File表单
                var file_array = document.getElementsByTagName("input");
                
                var is_null = false;
                //循环遍历判断是否有某一个File表单域的值为空
                for (var i = 0; i < file_array.length; i++) {
                    if (file_array[i].type == "file" && file_array[i].name.substring(0, 15) == "fileUploadTools") {
                        if (file_array[i].value == "") {
                            alert("某一附件为空不能继续添加");
                            is_null = true;
                            break;
                            
                        }
                        
                    }
                    
                }
                
                if (is_null) {
                    return;
                }
                
                a++;
                //新建file表单的基本信息
                var new_File_element = $('<input>');
                new_File_element.attr('type', 'file');
                new_File_element.attr('id', 'uploadFile' + a);
                new_File_element.attr('name', 'fileUploadTools.uploadFile');
                new_File_element.attr('size', 55);
                new_File_element.keydown(f);
                new_File_element.change(file_change);
                
                $('#fileForm').append(new_File_element);
                
                //新建删除附件的a标签的基本信息
                var new_a_element = $('<a>');
                new_a_element.html("删除附件");
                new_a_element.attr('id', "a_" + new_File_element.name);
                new_a_element.attr('name', "a_" + new_File_element.name);
                new_a_element.val($(new_File_element).attr('id'));
                new_a_element.attr('href', "#");
                new_a_element.click(remove_file);
                $('#fileForm').append(new_a_element);
                
                var new_br_element = $("<br>");
                $('#fileForm').append(new_br_element);
                var new_br_element = $("<br>");
                $('#fileForm').append(new_br_element);
            }
            
            function submitForm(){
                setTimeout("showprocessorBar()", 2000);
                return true;
            }
        </script>
    </head>
    <body>
        <div id="progr">
        </div>
        <br/>
        <s:form action="register" method="post" enctype="multipart/form-data" onsubmit= "return submitForm()">
            <table width="818" border="1">
                <tr>
                    <td width="176">
                        <div align="center">
                            用户账号
                        </div>
                    </td>
                    <td width="626">
                        <input type="text" name="username" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <div align="center">
                            用户附件
                            <br/>
                            <a href="javascript:insertFile()">添加附件</a>
                        </div>
                    </td>
                    <td id="fileForm">
                        <br/>
                    </td>
                </tr>
            </table>
            <input type="submit" value="submit this form" />
        </s:form>
        <br/>
        <table width="220" border="0" cellpadding="0" cellspacing="0" background= "ajax-loader.gif">
            <!--DWLayoutTable-->
            <tr>
                <td width="10" height="21" valign="top">
                    <table width="100%" border="0" cellpadding="0" cellspacing="0">
                        <!--DWLayoutTable-->
                        <tr>
                            <td width="10" height="21" bgcolor="#FFFFFF">
                                &nbsp;
                            </td>
                        </tr>
                    </table>
                </td>
                <td width="200">
                    <div align="right">
                        <div id="jidutiao" style="background-color: #FFFFFF; width: 100%; height: 100%">
                        </div>
                    </div>
                </td>
                <td width="10" valign="top">
                    <table width="100%" border="0" cellpadding="0" cellspacing="0">
                        <!--DWLayoutTable-->
                        <tr>
                            <td width="10" height="21" bgcolor="#FFFFFF">
                                &nbsp;
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </body>
</html>

猜你喜欢

转载自88548886.iteye.com/blog/1559174
今日推荐