spring mvc 提交表单实现文件上传服务器

一、准备好form表单,代码如下:

<form action="/App/upload/uploadfile?name='22.jpg'" method="post" target="id_iframe" enctype="multipart/form-data">  
	<p><input type="file" name="myfile" value="浏览文件"></p>  
	<p><input type="submit" value="上传"></p>  
</form>
<iframe id="id_iframe" name="id_iframe" style="display:none"></iframe>
1. App是应用的根目录,upload/uploadfile是服务端映射路径。
2. form表单提交类型一定要加上enctype="multipart/form-data",这是提交媒体文件的声明。
3. form表单提交的target="id_iframe",是为后台处理完成后返回结果刷新name为id_iframe的iframe。这样就不会刷新当前页面。

二、后台controller接收请求,代码如下:

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.log4j.Logger;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping(value="/upload")
public class UploadController {

	static Logger logger = Logger.getLogger(UploadController.class); 

	@RequestMapping(value="/uploadfile",method = RequestMethod.POST)
	@ResponseBody
	public String uploadFile(HttpServletRequest request){
		try{
			boolean isMultipart = ServletFileUpload.isMultipartContent(request); 
			logger.info("命中目标1:"+isMultipart);
			logger.info("文件名:"+request.getParameter("name"));
			if(isMultipart){  
				String fileName = request.getParameter("name");
				FileItemFactory factory = new DiskFileItemFactory();
				//ServletFileUpload对象的创建需要依赖FileItemFactory工厂将获得的上传文件FileItem对象保存至服务器硬盘,即DiskFileItem对象
				ServletFileUpload upload = new ServletFileUpload(factory);
				//设置允许上传的最大文件大小 4M
				upload.setSizeMax(4*1024*1024);
				//解析http请求消息头
				List<FileItem> fileItems = upload.parseRequest(new ServletRequestContext(request));
				Iterator iter = fileItems.iterator();
				//要执行while内逻辑,需在bean文件中有相应配置,后面会有说明。
				while(iter.hasNext()){
					FileItem item = (FileItem)iter.next();
					if(item.isFormField()){
						System.out.println("处理表单内容");
						processFormField(item,fileName);
					}else{
						System.out.println("处理上传文件");
						processUploadFile(item,fileName);
					}
				}
			} 
			return "upload file ok";
		}catch(Exception e){
			System.out.println("使用 fileupload 包时发生异常 ..."); 
			e.printStackTrace();
			return "upload file error";
		}
	}
	
	public void processFormField(FileItem item, String fileName) {
		String name = item.getFieldName();
		String value = item.getString();
		logger.info("表单域名为:" + name + "值为:" + value);
	}
	
	public void processUploadFile(FileItem item, String fileName){
		String filename = null;
		//获得文件名,此文件名包含路径
		if(fileName!=null){
			filename = fileName;
		}else{
			filename = item.getName();
		}
		logger.info("文件名:"+filename);
		if(filename!=null){
			File file = new File(filename);
			logger.info("创建文件对象File:"+file);
			String path = "/home/weblogic/";
			
			//判断路径是否存在
			File dirFile = new File(path);
			if(!dirFile.exists()){
				dirFile.mkdirs();
			}

			File filetoserver = new File(path,file.getName());  
			try{
				item.write(filetoserver); 
			}catch(Exception e){
				logger.info("文件上传服务器,写入异常");
				e.printStackTrace();
			}
			logger.info("文件:" + filetoserver.getName() + "上传成功");
		}else{
			logger.info("文件上传失败");
		}	
	}
}
在此,文件上传的实现,使用的是apache的ServletFileUpload,如果同时使用MultipartResolver 和ServletFileUpload,就会在iter.hasNext()返回false,然后整个循环就跳不出去了。整个问题产生的原因是Spring框架先调用了MultipartResolver 来处理http multi-part的请求。这里http multipart的请求已经消耗掉。后面又交给ServletFileUpload ,那么ServletFileUpload 就获取不到相应的multi-part请求。解决方法是加入multipartResolver来单独处理某些请求。
package com.util;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.multipart.commons.CommonsMultipartResolver;

/**
 *  @author yawenchen
 *  解决:Spring MultipartResolver 或者 ServletFileUpload 冲突导致获取不到http数据/Multipart数据为空
 */

public class MyMultipartResolver extends CommonsMultipartResolver{
    private String excludeUrls;     
    private String[] excludeUrlArray;  
      
    public String getExcludeUrls() {  
        return excludeUrls;  
    }  

    public void setExcludeUrls(String excludeUrls) {  
        this.excludeUrls = excludeUrls;  
        this.excludeUrlArray = excludeUrls.split(",");  
    } 
    
    /** 
     * 这里是处理Multipart http的方法。如果这个返回值为true,那么Multipart http body就会MyMultipartResolver 消耗掉.如果这里返回false 
     * 那么就会交给后面的自己写的处理函数处理例如刚才ServletFileUpload 所在的函数 
     * @see org.springframework.web.multipart.commons.CommonsMultipartResolver#isMultipart(javax.servlet.http.HttpServletRequest) 
     */  
    @Override  
    public boolean isMultipart(HttpServletRequest request) {  
        for (String url: excludeUrlArray) {  
	        // 这里可以自己换判断  
	        if (request.getRequestURI().contains(url)) {  
	            return false;  
	        }  
        }  
        return super.isMultipart(request); 
    }
}

三、在web.xml中这样配置

<bean id="multipartResolver" class="com.util.MyMultipartResolver">  
	<property name="excludeUrls" value="uploadfile"/>  
	<!-- url中带有uploadfile的http请求就不会被multipartResolver先解析-->
	<property name="defaultEncoding">
		<value>UTF-8</value>
	</property>
	<property name="maxUploadSize">
		<value>104857600</value><!-- 上传文件大小限制为31M,31*1024*1024 -->
	</property>
	<property name="maxInMemorySize">
		<value>4096</value>
	</property>
</bean>





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值