SSH框架中struts2上传文件的实现,页面不跳转刷新,使用FormData进行Ajax请求

在我们提交一个表单的时候,struts2会跳转到另一个页面进行处理

如action中如下配置


<result type="redirect">admin/index.jsp?ceshi=ceshi1</result>

此表示,当处理结果成功后会跳转到页面admin/index.jsp?ceshi=ceshi1

如果我们写配置,写成这样

<result type="redirect"></result>
即没有返回的视图页面,就会报错


2015-11-25 10:20:34,265 [ERROR] [org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler] - Exception occurred during processing request: null
java.lang.NullPointerException
	at org.apache.struts2.dispatcher.ServletRedirectResult.isPathUrl(ServletRedirectResult.java:276)
	at org.apache.struts2.dispatcher.ServletRedirectResult.doExecute(ServletRedirectResult.java:180)
	at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:191)
	at org.apache.struts2.dispatcher.ServletRedirectResult.execute(ServletRedirectResult.java:164)
因此,我们就有必要使用ajax来提交表单,但是有一个问题,如果表单中的类型是基本类型,如,文本,数字,时间等,用ajax是没有问题的

但是如果是文件类型,如我们上传文件,使用ajax按照传统的方法就会报错的,报错为参数不对

此时我们就需要使用FormData来完成

请看如下表单

<s:form action="ACupfile" method="post" enctype="multipart/form-data" id="formFile">
	<s:file id="file" name="file" onchange="saveFile();"/>
	<s:textfield id="filename" name="filename" />
</s:form>
上面的表单定义了一个表单,这个表单相信大家一定看得懂,需要注意的是enctype的值必须应该是"multipart/form/-data"

然后我们看看saveFile()函数是怎么写的

function saveFile(){
		$("#filename").val($("#file").val());
		var formData = new FormData($("#formFile")[0]);
		$.ajax({
			url:"ACupfile.action",
			type:"POST",
			data:formData,
			async:false,
			cache:false,
			dataType:"text",
			contentType:false,
			processData:false,
			success:function(){
				alert(123);
			},
			error:function(){
				alert(789);
			}
		});
		
	}
上面函数的关键点在于 

1,var formData = new FormData($("#formFile")[0])  得到一个formData 对象,参数为表单

2,contentType 为 false,因为FormData  已经封装进去了

3,processData 为 false,告诉ajax不用去处理数据(FormData),因为数据已经被封装

现在我们来看看struts.xml怎么配置的

<!-- 上传过程中临时保存的位置 -->
<constant name="struts.multipart.saveDir" value="d:\strutstemp\" />
以上设置的是上传文件临时的保存位置

<action name="ACupfile" class="upfile">
		    <result type="redirect">admin/index.jsp?ceshi=ceshi1</result>
		    <result name="input" type="redirect">admin/index.jsp?ceshi=ceshi</result>
		    <interceptor-ref name="fileUpload">
		        <param name="allowedType">
		            image/bmp,image/png,image/gif,image/jpeg,image/jpg
		        </param>
		        <param name="maximumSize">1048576</param>
		    </interceptor-ref>
		    <interceptor-ref name="defaultStack" />
</action>
因为是使用的ssh框架,所以上面的action的值是由spring提供的,上面的配置在于配置拦截器,拦截器fileUpload是自带的拦截器,我们需要配置上传文件的类型以及大小

然后需要添加默认的拦截器 defaultStack

然后我们看看action中如何实现接收数据,以下代码为我项目中直接拷贝,大家可以参考下。

public class UploadFile extends ActionSupport{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private List<File> file;
	private String filename;

	public List<File> getFile() {
		return file;
	}

	public void setFile(List<File> file) {
		this.file = file;
	}

	public String getFilename() {
		return filename;
	}

	public void setFilename(String filename) {
		this.filename = filename;
	}

	public String execute(){
		//获得项目的根地址,/LoveB
		String root = ServletActionContext.getRequest().getContextPath();
		//获得项目的实际路劲
		String path = (Thread.currentThread().getContextClassLoader().getResource("").toString()).replace('/', '\\').replace("file:", "").replace("classes\\", "").replace("WEB-INF\\", "").substring(1).replace("%20", " ");		
		
		//仅仅得到名字
		String fileName = filename.split("\\\\")[filename.split("\\\\").length-1];
		
		//仅仅得到一个服务器保存的名字:日期_fileName
		String newfilename = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+"_"+fileName;
		//获得新的文件名全路劲
		String newpath = path+"Face\\upload\\"+newfilename;
		
		//开始写入文件,图片采用二进制
		FileInputStream fis = null ;
		FileOutputStream fos = null ;
		DataOutputStream dos = null;
		DataInputStream dis = null;
		//获得文件,获得服务器临时的文件
		File file_client = new File(file.get(0).getPath());
		//服务器上的文件,没有就创建
		File file_service = new File(newpath);
		try {
			//创建磁盘输出对象,输出到磁盘
			fos = new FileOutputStream(file_service);
			dos = new DataOutputStream(fos);
			//创建磁盘输入对象     即是获得这个输入对象
			fis = new FileInputStream(file_client);
			dis = new DataInputStream(fis);
			
			int temp = dis.read();
			while(temp != -1){
				dos.write(temp);
				temp = dis.read();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return SUCCESS;
		
	}
}
以上就完成了ssh框架中struts2上传文件的实现


关于FormData  可以参考这里

https://developer.mozilla.org/zh-CN/docs/Web/Guide/Using_FormData_Objects


爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情Blog Img