zoukankan      html  css  js  c++  java
  • uploadify在struts2下的使用

    1、首先准备uploadify上传插件包,拷贝到项目目录下



    2、注意其中的特殊文件:uploadify-init.js文件,是包含了封装后的特殊函数:

    /**
     * uploadify上传插件相关JS
     */
    $.extend( {
    
    	/**
    	 * uploadify上传插件初始化设置
    	 * params:
    	 * 
    	 */
    	initUploadify : function(params) {
    		var opts = {
    				//'buttonImage' : '',				// 选择文件按钮图片
    				'buttonClass' : 'but but_blue',		// 选择文件按钮样式
    				'debug': false,						// 是否开启调试模式
    				'auto': true,						// 是否自动上传
    				'multi': true,						// 是否允许多个上传
    				'removeCompleted': true,			// 上传完毕上传列表是否消失
    				'removeTimeout': 0,					// 上传完毕到列表消失的间隔时间
    				'fileObjName': 'uploadFile',		// 上传文件数据的名字(服务器端获取文件时使用的名字)
    				'queueID': false,				// 装载进度条的标签ID
    				'progressData': 'percentage',		// 进度条效果percentage或speed 
    				'buttonText': '上传',				// 上传按钮文本内容
    				'formData' : {},				// 表单数据(json格式)
    				'method': 'post',					// 提交方法(post或get)
    				'fileSizeLimit': '2MB',				// 上传文件大小设置 单位可以是B、KB、MB、GB
    				'fileTypeDesc' : '*.gif; *.jpg; *.png',		// 选择文件框类型处提示文本
    				'fileTypeExts' : '*.gif; *.jpg; *.png',		// 上传时支持的文件类型
    				'swf': 'js/uploadify/uploadify.swf',// swf文件位置(必设参数,插件自带文件,不可替换)
    				'width': 120,						// 上传按钮宽度
    				'height': 30,						// 上传按钮高度
    				'successTimeout': 999999,			// 上传超时时间,若达到时间服务器没有响应,则当作成功(很扯淡的设置,默认为30秒)
    				'uploader': '',			// 服务器处理上传的Action 
    				'queueSizeLimit': 10,				// 允许一次上传的文件数
    				'uploadLimit': 999999,				// 允许的总上传文件次数(刷新页面后重置)
    				//'overrideEvents' : [],			// 设置不执行的默认事件				
    				// 选中文件时事件
    				'onSelect': function (event, queueID, fileObj) {
    					
    				},				
    				// 上传文件出错事件
    				'onUploadError': function (file,errorCode,errorMsg,errorString,swfuploadifyQueue) {					
    					alert(errorMsg);
    				},				
    				// 上传完成时事件
    				'onUploadComplete': function (file) {
    					
    				},				
    				// 上传时发生错误事件
    				'onUploadError': function (file, errorCode, errorMsg) {
    					var msg = "服务器故障。";
    					switch(errorCode) {
    						case -100:
    							msg = "上传的文件数量已经超出系统限制的"+$('#file_upload').uploadify('settings','queueSizeLimit') + "个文件。";
    		                    break;
    		                case -110:
    		                    msg = "文件 ["+file.name+"] 大小超出系统限制的" + $('#file_upload').uploadify('settings','fileSizeLimit') + "大小。";
    		                    break;
    		                case -120:
    		                	msg = "文件 ["+file.name+"] 大小异常。";
    		                    break;
    		                case -130:
    		                	msg = "文件 ["+file.name+"] 类型不正确。";
    		                    break;
    		                case -280:
    		                	return;
    					}
    					alert(msg);
    				},				
    				// 检测Flash失败调用
    		        'onFallback': function(){
    					var fallBackMsg = '您未安装Flash控件,无法上传图片!请安装FLASH控件后再试。';
    					alert(fallBackMsg);
    		        },		        
    		        // 成功上传到服务器,服务器返回相应信息(服务器回写的数据存放于data中)
    		        'onUploadSuccess': function(file, data, response){
    		        	
    		        },
    		        inputFile:"#file_upload"
    			};
    		if (typeof params !== "undefined")
    			$.extend(opts,params);
    		
    		if (typeof opts.uploader === "undefined" || opts.uploader === ""){
    			alert("必须指定上传的地址");
    			return;
    		}
    		if (typeof opts.inputFile === "undefined" || opts.inputFile === ""){
    			alert("没有指定上传表单元素");
    			return;
    		}
    		$(opts.inputFile).uploadify(opts);
    	}
    });
    


    3、客户端调用实例

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="http://localhost:8080/snjob/">    
        <title>上传示范</title>
       	
    <link rel="stylesheet" href="js/uploadify/uploadify.css" type="text/css" />
    <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="js/uploadify/jquery.uploadify.min.js"></script>
    <script type="text/javascript" src="js/uploadify/uploadify-init.js"></script>
       	<style type="text/css">
       		body{
       			font-size:12px;
       		}
       		.uploadform{
       			background-color: gray;
       			border:1px solid;
       		}
       		table{
       			80%;
       			border- 1px;  			
       		}
       	</style>
       	<script type="text/javascript">
       		$(function(){
       			
       		   	$.initUploadify({
    				inpufFile:"#file_upload",
    				uploader:'http://localhost:8080/snjob/corpasyn/UploadAction!uploadMethod1.action',
    				formData:{param1 : "jiang"},
    				onUploadSuccess:function(file, ptl, response){
    					eval("var ptl = "+ptl);
    					var d = new Date();
    					
    		        	if (ptl.status==="Success"){
    						var tr = "<tr>";
    						tr+="<td>"+file.name+"</td>";
    						tr+="<td>"+(file.size/1024)+"K</td>";
    						tr+="<td>"+d+"</td>";
    						tr+="<td><a href='2/"+ptl.data+"'>下载</a></td>";
    						tr+="</tr>";
    						$("table tbody").append(tr);
    				    } else {
    					    alert(ptl.msg);
    				    }
    		        }
       	   		 });
       	   	});
       	</script>
      </head>  
      <body>
      	<h3>上传文件示范</h3>
      	<div class="uploadform">
      		<input id="file_upload" type="file" name="file_upload" />
      	</div>
      	<h5>文件列表</h5>
      	<div>
      		<table id="upfiles" border="1">
      			<tbody>
      				<tr>
    	  				<th>文件名</th>
    	  				<th>文件大小</th>
    	  				<th>上传时间</th>
    	  				<th>操作</th>
      				</tr>
      			</tbody>
      		</table>
      	</div>
      	
      	<a href="demo/corp_feedback.jsp"><h3>Ajax异步加载示范和Ajax分页示范</h3></a>
      </body>
    </html>
    


    4、运行效果:



    5、看一下最关心的服务器代码是如何编写的

    服务器采用Struts2,具体Action的设计如下:


    我们要直接使用的是UploadDemoAction。

    BaseAction源码:

    package org.job.web.action;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.security.InvalidParameterException;
    import java.text.MessageFormat;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.annotation.Resource;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    import org.apache.struts2.ServletActionContext;
    import org.apache.struts2.interceptor.ServletRequestAware;
    import org.apache.struts2.interceptor.ServletResponseAware;
    import org.apache.struts2.json.annotations.JSON;
    import org.apache.struts2.util.ServletContextAware;
    import org.job.biz.ServiceTemplate;
    
    
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    
    
    /**
     * Action类的基类,实现了ServletRequestAware接口、ServletResponseAware接口、ServletContextAware接口用于注入Servlet对象,因此与Servlet API有耦合
     * 也可以采用ServletActionContext.getXxx()方法实现访问Servlet API更加优雅
     * @author 江橦
     *
     */
    
    public abstract  class BaseAction extends ActionSupport implements ServletRequestAware,ServletResponseAware,ServletContextAware,IAction {	
    	
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 7897085684034354314L;
    	
    	
    	
    
    	/**
    	 * 添加属性到请求上下文
    	 * @param key
    	 * @param value
    	 */
    	protected void addAttr(String key,Object value,VScope...scopes){
    		VScope scp = scopes==null||scopes.length==0?VScope.REQ:scopes[0];
    		switch (scp) {
    		case PAGE:
    			((java.util.Map<String,Object>)ActionContext.getContext().get("page")).put(key, value);
    			break;
    		case REQ:
    			((java.util.Map<String,Object>)ActionContext.getContext().get("request")).put(key, value);
    			break;
    		case SESSION:
    			ActionContext.getContext().getSession().put(key, value);
    			break;
    		case APPLICATION:
    			ActionContext.getContext().getApplication().put(key, value);
    			break;
    		default:
    			break;
    		}
    		
    	}	
    	
    	
    	
    	
    	
    	
    	/**
    	 * 获得当前登录的会员用户
    	 * @return
    	 */
    	protected <T> T getLoginedPersonUser(){
    		Object u = ActionContext.getContext().getSession().get(LOGINED_PERSON_USER);
    		return u==null?null:(T)u;
    	}
    	
    	/**
    	 * 获得当前登录的企业用户
    	 * @return
    	 */
    	protected <T> T getLoginedCorpUser(){
    		Object u = ActionContext.getContext().getSession().get(LOGINED_CORP_USER);
    		return u==null?null:(T)u;
    	}
    	
    	
    	/**
    	 * 获得当前登录的运营商用户
    	 * @return
    	 */
    	protected <T> T getLoginedManagerUser(){
    		Object u = ActionContext.getContext().getSession().get(LOGINED_MANAGE_USER);
    		return u==null?null:(T)u;
    	}
    	
    	
    	
    	protected HttpServletRequest request;
    	protected HttpServletResponse response;
    	protected ServletContext servletContext;
    	/* *
    	 *注入 HttpServletRequest
    	 */
    	
    	public void setServletRequest(HttpServletRequest arg0) {
    		// TODO 子类重写
    		this.request = arg0;
    	}
    
    	/* *
    	 * 注入 HttpServletResponse
    	 */
    	
    	public void setServletResponse(HttpServletResponse arg0) {
    		// TODO 子类重写
    		this.response = arg0;
    	}
    
    	/* *
    	 * 注入 setServletContext
    	 */
    	
    	public void setServletContext(ServletContext arg0) {
    		// TODO 子类重写
    		this.servletContext = arg0;
    	}
    	
    	
    	
    	Map<String,Object> _paramMap = new HashMap<String,Object>();
    	/**
    	 * 获得表单元素值
    	 * @param name
    	 * @return
    	 */
    	public Object getParam(String key){
    		if (_paramMap.size()==0){
    			Map<String,Object> paramMap = ActionContext.getContext().getParameters();		
    			for (Map.Entry<String,Object> kvp : paramMap.entrySet()) {
    				_paramMap.put(kvp.getKey().toUpperCase(),kvp.getValue());
    			}
    		}			
    		
    		if(!_paramMap.containsKey(key.toUpperCase()))
    			return "";
    		Object[] values =  (Object[])_paramMap.get(key.toUpperCase());
    		if (values==null || values.length==0)
    			return "";
    		if (values.length==1)
    			return values[0]==null?"":values[0];
    		return values;	
    	}
    	
    	/**
    	 * 绑定参数到对象属性
    	 * @param entity
    	 * @param params
    	 */
    	public void bindParam2Bean(Object entity){
    		
    		Map<String,Object> paramMap = ActionContext.getContext().getParameters();
    		if (paramMap==null || paramMap.size()==0)
    			throw new InvalidParameterException("没有有效的参数可以绑定");
    		Class classzz = entity.getClass();
    		//將所有私有字段裝入Map<字段名,字段對象>
    		Map<String,Field> fieldMap = new HashMap<String,Field>();
    		for (Field f : classzz.getDeclaredFields()) {
    			fieldMap.put(f.getName().toUpperCase(),f);
    		}
    		Field f = null;
    		Object fvalue = null;
    		for (Map.Entry<String,Object> kvp : paramMap.entrySet()) {
    			try {
    				Object[] values = (Object[])kvp.getValue();
    				if (null != values && values.length==1){
    					//f = classzz.getDeclaredField(kvp.getKey());
    					f = fieldMap.get(kvp.getKey().toUpperCase());//從HashMap中取得字段對象[不區分大小寫]
    					if ( null == f)
    					 	continue;
    					f.setAccessible(true);
    					if (f.getType()==String.class){
    						f.set(entity, values[0]);
    					}else{
    						fvalue = f.getType().getDeclaredMethod("valueOf",String.class).invoke(null, values[0]);
    						f.set(entity, fvalue);
    					}
    						
    				}
    			} catch (Exception e) {
    				if (super.LOG.isInfoEnabled())					
    					super.LOG.info(java.text.MessageFormat.format("封装请求参数{0}到JavaBean的{1}属性失败[{2}]", kvp.getKey(),f.getName(),e.getMessage()));
    			}
    		}
    	}
    
    	protected ServiceTemplate serviceTemplate = new ServiceTemplate();
    	
    	/**
    	 * 存放验证的消息
    	 */
    	private Map<String,String> validateMsgs = new HashMap<String,String>();
    	
    	protected void addValidateMsg(String msgKey,String msgValue){
    		validateMsgs.put(msgKey, msgValue);
    		request.setAttribute(VALIDATE_MSG, this.validateMsgs);
    	}
    	
    	protected Boolean isValid(){
    		if(this.validateMsgs.size()>0)
    			request.setAttribute(VALIDATE_MSG, this.validateMsgs);
    		return this.validateMsgs.size()==0;
    	}
    	
    	/**
    	 * 獲得客戶端IP
    	 * @param request
    	 * @return
    	 */
    	public String getIpAddr(HttpServletRequest request) {
    		String ip = request.getHeader("x-forwarded-for");
    		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    		ip = request.getHeader("Proxy-Client-IP");
    		}
    		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    		ip = request.getHeader("WL-Proxy-Client-IP");
    		}
    		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    		ip = request.getRemoteAddr();
    		}
    		return ip;
    	}
    }
    


    BaseJSONAction源码:

    package org.job.web.action;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    
    import net.it028.foundation.global.ExceptionUtil;
    
    import org.apache.commons.beanutils.ConvertUtils;
    import org.apache.commons.lang.StringUtils;
    import org.apache.commons.lang.exception.ExceptionUtils;
    import org.job.uptl.*;
    import org.job.uptl.UProtocol.*;
    import org.job.web.convertor.*;
    
    
    /**
     * 
     * 所有客户端接口请求的Action的基类
     * @author jiangtong
     *
     */
    public class BaseJSONAction extends BaseAction {
    
    	static { 
    	      ConvertUtils.register(new SqlDateConverter(null), java.sql.Date.class); 
    	      ConvertUtils.register(new SqlTimestampConverter(null), java.sql.Timestamp.class); 
    	} 
    
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = -3138932274689672883L;
    
    	
    	/**
    	 * 執行子類Action的模板方法
    	 * @param actionCallback
    	 * @return
    	 */
    	public String executeAction(IExecuteActionCallback actionCallback){
    		String result = super.SUCCESS;
    		try {
    			getUp().status = ERspStatus.Success;
    			if (actionCallback!=null)
    				result = actionCallback.execute(this);
    			getUp().msg = "success";
    		}catch (Exception e2) {
    			getUp().status = ERspStatus.Exception;			
    			getUp().msg=ExceptionUtil.getMsg(e2);
    			if (getUp().msg.contains("ConstraintViolationException")){
    				getUp().msg = "数据项重复录入";
    			}
    		}
    		return result;
    	}
    	
    	/**
    	 *通讯协议 
    	 */	
    	private UProtocol up;
    
    	/**
    	 *获得通讯协议 
    	 */
    	public UProtocol getUp() {
    		if (up==null)
    			up= new UProtocol();
    		return up;
    	}
    
    	/**
    	 *设置通讯协议 
    	 */
    	public void setUp(UProtocol up) {
    		this.up = up;
    	}
    	
    }
    


    BaseUploadAction源码:

    package org.job.web.action;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.UUID;
    
    import net.it028.foundation.global.StringUtils;
    
    import org.apache.struts2.ServletActionContext;
    
    public class BaseUploadAction extends BaseJSONAction {
    
    	private static final long serialVersionUID = 5196594946316620265L;
    
    	private String savePath;
    	private File uploadFile;
    	private String uploadContentType;
    	private String filename;
    
    	/**
    	 * 保存路径,通过struts配置文件注入
    	 * 
    	 * @return
    	 */
    	public String getSavePath() {
    		return ServletActionContext.getRequest().getSession()
    				.getServletContext().getRealPath(savePath);
    	}
    
    	public void setSavePath(String savePath) {
    		this.savePath = savePath;
    	}
    
    	/**
    	 * 上传的文件
    	 * 
    	 * @return
    	 */
    	public File getUploadFile() {
    		return uploadFile;
    	}
    
    	public void setUploadFile(File uploadFile) {
    		this.uploadFile = uploadFile;
    	}
    
    	/**
    	 * 上传文件的内容类型
    	 * 
    	 * @return
    	 */
    	public String getUploadContentType() {
    		return uploadContentType;
    	}
    
    	public void setUploadContentType(String uploadContentType) {
    		this.uploadContentType = uploadContentType;
    	}
    
    	/**
    	 * 上传的文件名
    	 * 
    	 * @return
    	 */
    	public String getFilename() {
    		return filename;
    	}
    
    	public void setFilename(String filename) {
    		this.filename = filename;
    	}
    
    	/**
    	 * 保存文件
    	 */
    	protected String saveFile(String filename) {
    		String savePath = getSavePath();
    		File fileSavePath = new File(savePath);
    		if (!fileSavePath.exists() && !fileSavePath.mkdirs()) {// 如果目录不存在则主动创建
    			throw new RuntimeException("保存文件前创建目录路径失败......");
    		}
    		FileOutputStream fos = null;
    		FileInputStream fis = null;
    
    		String saveFileName = filename;
    		if (filename == null || "".equals(filename))
    			saveFileName = StringUtils.getUniqueString()
    					+ getFilename().substring(getFilename().lastIndexOf("."));
    		try {
    			// 以服务器的文件保存地址和源文件名建立上传文件输出流
    			fos = new FileOutputStream(savePath + File.separatorChar
    					+ saveFileName, false);
    			// 以上传文件建立一个文件上传流
    			fis = new FileInputStream(getUploadFile());
    			// 将上传文件的内容写入服务器
    			byte[] buffer = new byte[1024 * 1024];
    			int len = 0;
    			while ((len = fis.read(buffer)) > 0) {
    				fos.write(buffer, 0, len);
    			}
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		} finally {
    			try {
    				if (fos != null) {
    					fos.flush();
    					fos.close();
    				}
    				if (fis != null) {
    					fis.close();
    				}
    			} catch (IOException e) {
    				throw new RuntimeException(e);
    			}
    		}
    
    		return saveFileName;
    	}
    
    }
    


    UploadDemoAction源码:

    package org.job.enterprice.web;
    
    import java.sql.Timestamp;
    import java.util.Date;
    
    import javax.annotation.Resource;
    
    import net.it028.foundation.global.DateUtil;
    
    import org.apache.commons.lang.xwork.StringUtils;
    import org.job.uptl.UPDataProtocol;
    import org.job.web.action.BaseJSONAction;
    import org.job.web.action.BaseUploadAction;
    import org.job.web.action.IExecuteActionCallback;
    
    public class UploadDemoAction extends BaseUploadAction {
    
    	private static final long serialVersionUID = -871233872187381L;
    
    	/**
    	 * 上传文件示范1
    	 * 
    	 * @return
    	 */
    	public String uploadMethod1() {
    		return this.executeAction(new IExecuteActionCallback() {
    			
    			@Override
    			public String execute(BaseJSONAction action) {				
    				String param1 = getParam("param1").toString();
    				
    				System.out.println("接收到的上传参数:"+param1);
    				
    				// 处理文件扩展名
    				String fileName = getFilename();
    				//取得扩展名
    				String exName = fileName.substring(fileName
    						.lastIndexOf(".") + 1);
    				//新文件名[根据自己的规则生成]
    				//String nfilename = DateUtil.getTimestamp().getTime()+"."+exName;
    				
    				String nfilename = saveFile("");//该方法返回保存后的文件名,如果给定的文件无效将重新生成	
    				
    				UPDataProtocol up = new UPDataProtocol();
    				up.setData(nfilename);
    				setUp(up);
    				
    				return SUCCESS;
    			}
    		});
    	}
    }
    

    Struts配置示范:

    <package name="corpasyn_demo" namespace="/corpasyn" extends="jobcommon">
    <!-- 上传示范 -->
    		<action name="UploadAction" class="org.job.enterprice.web.UploadDemoAction">
    			<!-- 保存目录 -->
    			<param name="savePath">/2</param>
    			<!-- 返回格式 -->
    			<result type="json">
    				<param name="ignoreHierarchy">false</param>
    				<param name="root">up</param>
    			</result>
    			<!-- 系统上传拦截器 -->
    			<interceptor-ref name="fileUpload">
    				<param name="allowedExtensions">.jpg,.gif,.png,.bmp</param>
    				<param name="maximumSize">2097152</param>
    			</interceptor-ref>
    			<!-- 自定义身份认证拦截器 -->
    			<interceptor-ref name="authenInterceptStack"></interceptor-ref>
    		</action>
    		
    </package>

    瞥一眼jobcommon这个包的关键代码:

    <!-- 通用Action -->
    	<package name="jobcommon" namespace="/" extends="json-default">
    		<interceptors>
    			<interceptor name="authenticationInterceptor" class="org.job.web.interceptor.AuthenticationInterceptor" />
    			<!-- 自定义拦截器需要和缺省拦截器栈整合,否则可能丢失struts2的一些既定功能,比如参数赋值-->
    			<interceptor-stack name="authenInterceptStack">						
    				<interceptor-ref name="defaultStack"></interceptor-ref>
    				<interceptor-ref name="authenticationInterceptor"></interceptor-ref>
    			</interceptor-stack>			
    		</interceptors>
    				
    		<!--Action的缺省拦截器[身份认证和授权]  -->
    		<default-interceptor-ref name="authenInterceptStack" />
    </package>


  • 相关阅读:
    Spring
    JavaWeb
    JDBC
    MYSQL
    IDEA个人常用快捷键
    Web前端-JAVASCRIPT
    Web前端-HTML
    注解与反射
    多线程
    区块链 ATS多策略量化机器人简介
  • 原文地址:https://www.cnblogs.com/riskyer/p/3236989.html
Copyright © 2011-2022 走看看