`

Struts2下利用JSON结合jQuery Form插件实现文件上传的问题与解决办法

阅读更多

这两天要实现一个文件上传的功能。

开发环境是:服务器端Struts2,客户端jQuery,需要使用Ajax来实现,我在用Struts2开发Ajax应用时,都是基于JSON来实现的。

 

理论上文件上传是无法用Ajax来实现的:ajax基于javascript和xmlhtttp,其与服务器通信都是通过传递字符串。另外出于安全考虑,javascript是不能操作文件的,因此从理论上来说javascript是无法实现文件上传的。

 

实际上只能实现一种无刷新文件上传,从实现效果上类似于Ajax的无刷新与服务器进行通信。

 

其原理是:给file控件所在的form加上 target 属性,将返回结果页面定向到一个隐藏的 iframe。

 

在具体的实现上,我使用了jQuery的form插件来完成,该插件对文件上传的功能进行了封装,其实现原理也类似于上面的分析。但可以方面的在进行提交之前与提交之后添加callback函数。

 

在实现中出现了一个问题是:如果用Struts2的JSON返回结果,上传完成以后,不会调用form插件success对应的callback函数,并自动弹出JSON信息的下载页面,使用记事本打开可以看到对应的JSON信息。


对于这个问题有两个解决办法:

1. 不使用JSON方法,将Struts2的结果类型换成redirect

2. 不使用JSON方法,将Struts2的结果类型换成plaintext,直接输出处理情况信息

 

其他的一些解决办法是:可以使用Flex相关的技术来实现,看了一下Google Doc的文件上传,就是使用flash来实现的。

plaintext可以直接将处理结果信息写到Response,不需要另外创建新的结果页面,最后我采用了这种办法。 具体如下:

代码情况如下:

JSP页面:uploadDoc.jsp

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>上传文件</title>
<script src="../js/jquery.js" type="text/javascript"></script>
<script src="../js/jquery.form.js" type="text/javascript"></script>
	<script language="javascript">	
      $(document).ready(function(){
          var validateForm = function() {
	        	var fileName = $('#theFile').val();
	  			var m=parseInt(fileName.toString().lastIndexOf("."))+1;
	  		    var extVal=fileName.toString().substr(m);
	  			if(extVal!="doc") {
	  				alert('文件类型必须为Word文件!');
	  				return false;
	  			}
	  			$('#upMessage').html('文件上传中,请等待... ...');
	  			return true;	
        };

          var showResponse = function(data,status) { 
              $('#upMessage').fadeIn("fast",function(){
             	 
              });
     		return true;
           };
    	  var options={		
    	    	target : '#upMessage',	
  				url : 'AjaxUploadProductDoc!upload.action',
  				beforeSubmit: validateForm,
  				success : showResponse,
  				resetForm:true
  			};
    	  $('#upForm').ajaxForm(options);    	  
      });     
	</script>
</head>
<body>
	<form id="upForm" method="POST" enctype="multipart/form-data">
		上传文件:<input type="file" name="file" id="theFile"/>
		<br/>
		<input type="submit" value="提交" />
		<div id="upMessage" style="displan:hidden"></div>
	</form>
	</body>
</html>

 

后台Java类: AjaxUploadProductDocAction.java

package org.xtwh.product.action;

import org.apache.log4j.Logger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 处理上传DOC文件
 * @author user
 *
 */
public class AjaxUploadProductDocAction extends ActionSupport{
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(AjaxUploadProductDocAction.class);

	
	private static final int BUFFER_SIZE = 16 * 1024;
	
	private File file;
	private String contentType;	//上传文件的MIME类型
	private String fileName;	//上传文件的文件名,该文件名不包括文件的后缀
		
	private boolean success;	//标识上传是否成功
	private static final String TEXT = "text";
	
//访问页面
	public String execute() {
		return INPUT;
	}

//上传文件
	public String upload() throws IOException {
		if(fileName == null || fileName.equals("")) {
			success = false;
			printMessage();
			return TEXT;
		}		
			
		if (file != null) {
			//保存文件					
			copy(file, docFile);
			
			//进行其他处理
		} 		
		success = true;
		message = "上传文件成功。";
		printMessage();
		return TEXT;
	}
	
/**
 * 判断上传文件夹中是否有同名文件
 * @return
 */
	private boolean hasSameFile() {
		
		return false;
	}
	
//输出信息到response
	private void printMessage() throws IOException {
		ActionContext ctx = ActionContext.getContext();
		HttpServletResponse response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE); 
		response.setContentType("text/plain;charset=utf-8");
		response.setHeader("Cache-Control", "no-cache");
		
		PrintWriter pw = null;
		try {
			StringBuffer sb = new StringBuffer();
			if(success) {
				sb.append("上传文件成功!");				
			}else {
				sb.append("上传文件失败");
			}
			
			pw = response.getWriter();
			pw.print(sb.toString());
			
		} catch (IOException e) {
			logger.error("输出 错误!");
			e.printStackTrace();
		} 
		finally {
			if(pw != null) {
				pw.close();
				pw = null;
			}
		}
	}

//copy file
	private static void copy(File src, File dst)  {
        try  {
           InputStream in = null ;
           OutputStream out = null ;
            try  {                
               in = new BufferedInputStream( new FileInputStream(src), BUFFER_SIZE);
               out = new BufferedOutputStream( new FileOutputStream(dst), BUFFER_SIZE);
                byte [] buffer = new byte [BUFFER_SIZE];
                while (in.read(buffer) > 0 )  {
                   out.write(buffer);
               } 
            } finally  {
                if ( null != in)  {
                   in.close();
               } 
                 if ( null != out)  {
                   out.close();
               } 
           } 
        } catch (Exception e)  {
           e.printStackTrace();
       } 
   } 
	
	

	public boolean isSuccess() {
		return success;
	}
	public void setFile(File file) {
		this.file = file;
	}
	public void setFileContentType(String contentType) {
		this.contentType = contentType;
	}
	public void setFileFileName(String fileName) {
		this.fileName = fileName;
	}


	
}

 配置文件:

<action name="AjaxUploadProductDoc" class="org.xtwh.product.action.AjaxUploadProductDocAction">
	<result name="input">/product/uploadDoc.jsp</result>
	<result name="xml" type="plaintext"></result>
</action>
分享到:
评论
3 楼 weir2009 2011-11-22  
ie是解决了,火狐又不行了,老兄。
2 楼 ustcfxx 2009-12-25  
zhaoliaoyuan 写道
不知是否可以上传大型文件,200m以下就可以啦?[size=xx-small][/size]

可参见:http://hanxin830311.iteye.com/blog/200990
1 楼 zhaoliaoyuan 2009-12-24  
不知是否可以上传大型文件,200m以下就可以啦?[size=xx-small][/size]

相关推荐

    struts2+jquery之form插件实现异步上传

    通过以上步骤,你就可以实现Struts2和jQuery form插件结合的异步文件上传功能。这个过程中,关键在于正确配置和交互,以及处理好前后端的数据交换。记得在实际项目中,还需要考虑文件大小限制、错误处理、安全性(如...

    struts2+jquery之form插件实现异步上传图片并显示

    在这个场景中,我们将深入探讨如何利用jQuery的form插件来实现在Struts2环境中进行图片上传,并在前端进行实时预览。 1. **Struts2 框架**: Struts2是一个基于MVC设计模式的Java Web应用框架,它提供了一种组织...

    使用Struts2的JSON插件来实现JSON数据传递

    然后,在Struts2的配置文件struts.xml中启用JSON插件,通常通过以下配置实现: ```xml &lt;constant name="struts.enable.SlashesInActionNames" value="true"/&gt; &lt;constant name="struts.action.extension" value=...

    Struts2+jQuery(不用JSON)实现局部刷新

    - **Struts2的JSON插件**:虽然题目要求不使用JSON,但通常情况下,Struts2通过JSON插件返回数据给jQuery是最方便的方式。不过,我们可以通过设置Content-Type为"text/plain"或"text/html",让Struts2返回非JSON...

    Struts2与JSON

    将Struts2与JSON整合,可以实现高效、动态的Web交互。 首先,我们要理解Struts2整合JSON的基本流程。在Struts2中,我们可以通过Action类返回一个JSON结果类型,这样Struts2会自动将Action的属性转化为JSON格式并...

    jquery 插件ajaxfileupload与struts2结合 实现异步上传图片

    在本文中,我们将深入探讨如何将jQuery插件AjaxFileUpload与Struts2框架结合,以实现异步图片上传的功能。这种技术在现代Web应用中非常常见,它提升了用户体验,允许用户在不刷新整个页面的情况下上传文件,特别是...

    struts2+ajax+jquery

    在这个"struts2+ajax+jquery"的主题中,我们将深入探讨如何利用Struts2、jQuery和Ajax技术实现Web页面的异步交互。 首先,Struts2作为MVC框架,它的核心是Action,它负责处理用户的请求,并通过配置的Result返回...

    Struts2+jquery.form.js实现图片与文件上传的方法

    在本文中,我们将深入探讨如何使用Struts2框架与jquery.form.js插件来实现图片和文件的异步上传。这是一个常见的需求,特别是在构建交互性强的Web应用时,用户需要能够方便快捷地上传文件,如图片。 首先,让我们...

    AJAX 想Struts2后台传送Json数据并向前台返回Json格式的数据

    在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种技术,它允许页面在不刷新整个页面的情况下与服务器交换数据并更新部分网页内容。而Struts2是一个强大的MVC(Model-View-Controller)框架,它广泛应用...

    struts2下jquery-ui的全部实例

    - **Slider**:创建一个滑动条,允许用户通过拖动选择值,可结合Struts2实现数据提交。 - **Tabs**:在不同选项卡中展示不同的内容,提高页面布局的清晰度。 在提供的`struts2_jquery_ui_all`压缩包中,应包含...

    java struts2 文件上传 支持大文件

    Struts2框架提供了丰富的插件和配置来支持文件上传,其中包括进度条显示,以提升用户交互体验。以下是对这个话题的详细解释。 1. **Struts2 文件上传基础** - Struts2 使用 `struts2-core` 包中的 `...

    JQuery EasyUI 整合struts2 代码下载

    标题 "JQuery EasyUI 整合struts2 代码下载" 涉及到的是一个Web开发中的技术组合,主要集中在前端的JQuery EasyUI框架与后端的Struts2框架的集成应用。JQuery EasyUI是一个基于jQuery的UI库,提供了丰富的组件,如...

    ajax_struts2_上传与下载_无刷新

    2. 采用jquery.form.js实现ajaxForm提交表单或上传文件到服务器。 3. 在struts2的Action通过2种不同的实现方法返回json格式的字符串。 4. 针对商品实现简单无刷新上传与下载 4. 批量导入数据采用的是导入test文件夹...

    浅谈struts1 & jquery form 文件异步上传

    在本文中,我们将探讨如何使用Struts1框架与jQuery Form插件实现文件的异步上传。Struts1是一个历史悠久的MVC(Model-View-Controller)框架,虽然它已不再是最新的技术,但在许多遗留系统中仍然被广泛使用。jQuery ...

    struts2+ajaxForm

    结合以上内容,我们可以看到Struts2和AjaxForm的集成使得Web应用在处理表单数据时更加高效,同时jQuery和validate插件的使用则确保了表单数据的质量,提供了更好的用户体验。在实际开发中,这样的组合可以大大提高...

    Struts2文件上传带进度条页面无刷新

    "Struts2文件上传带进度条页面无刷新"的实现涉及多个技术点,包括Struts2的文件上传插件、AJAX异步通信以及前端进度条展示。 首先,Struts2的文件上传依赖于`struts2-upload-plugin`。这个插件扩展了Struts2的核心...

    ajaxFileUpload+struts2实现多文件上传(源码)

    在本文中,我们将深入探讨如何使用`ajaxFileUpload`与`Struts2`框架结合,实现多文件上传功能。这个示例源码提供了一个实用的方法,使得用户可以在不刷新整个页面的情况下,上传多个文件,提高了用户体验。 首先,`...

    jquery文件上传例子(两种方式)

    另一种jQuery文件上传方法是使用插件,例如`plupload`、`jQuery Form Plugin`或者`jQuery File Upload`。这些插件提供更丰富的功能,如多文件上传、进度条显示、错误处理等。`jqueryUpload.html`可能演示了其中一种...

Global site tag (gtag.js) - Google Analytics