`
orange_chen
  • 浏览: 3422 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

common-fileupload与springMVC实现文件上传

    博客分类:
  • java
阅读更多

     上周为项目增加了文件上传功能,用于接收http接口上传的文件。现将一些心得与总结记录下来。

      项目使用环境:JDK6、Tomcat6

      我尝试过两种方式来实现文件上传的功能,分别为common-fileupload与spingMVC的文件上传。

      方式一、common-fileupload实现文件上传

      相关jar包:commons-fileupload-1.3.1.jar,commons-io-1.4.jar

 /**
    * 1.获取项目所在路径
    * 2.构建文件存放路径
    * 3.构建文件相对路径
    * 4.设置request的字符集
    * 5.创建磁盘文件工厂
    * 6.设置缓冲大小、上传文件大小限制、临时文件夹
    * 7.得到上传文件名
    * 8.将文件保存到服务器端
 * @throws UnsupportedEncodingException 
    */
	public void fileUpload(HttpServletRequest request, String fload) throws Exception {
		Date currData = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String classPath=this.getClass().getClassLoader().getResource("").getPath();
        String projectPath=classPath.substring(0, classPath.length()-"/WEB-INF/classes/".length());
        String projectName=projectPath.substring(projectPath.lastIndexOf("/")+1);
        String filePath=projectPath+fload+"/"+sdf.format(currData);  //文件存放路径
        String relativePath="/"+projectName+fload+"/"+sdf.format(currData); //文件存放相对路径
        String tempUploadPath=projectPath+"/"+"tempUpload";    //临时文件夹路径为
        
        System.out.println("文件存放的文件夹为----:"+filePath);
        System.out.println("文件存放的文件夹相对路径为----:"+relativePath);
        System.out.println("临时文件夹路径为----:"+tempUploadPath);
        
		request.setCharacterEncoding("UTF-8");
		final long MAX_SIZE=100 * 1024 * 1024;  //上传文件大小限制
		DiskFileItemFactory dfif = new DiskFileItemFactory();  // 实例化一个硬盘文件工厂,用来配置上传组件ServletFileUpload
		dfif.setSizeThreshold(40960000);  // 设置缓冲(字节),这个值决定了是fileinputstream还是bytearrayinputstream
		File tempUploadFload = new File(tempUploadPath);
		if(!tempUploadFload.isDirectory()){
			tempUploadFload.mkdirs();
		}
		dfif.setRepository(tempUploadFload);  //设置临时文件夹路径
		
		ServletFileUpload sfu = new ServletFileUpload(dfif);
		sfu.setFileSizeMax(MAX_SIZE); //设置上传文件大小
		sfu.setHeaderEncoding("UTF-8");
		
		List<FileItem> fils=null;
		try {
			fils = sfu.parseRequest(request);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		Iterator<FileItem> fileite = fils.iterator();
		String fileName="";
		String fileType="";
		String fileAllPath="";
		String relativeAllPath="";
		long   fileSize=0L;
		
		while(fileite.hasNext()){
			FileItem fileItem = fileite.next();
			
			if(fileItem==null || fileItem.isFormField() ){  //忽略简单form字段
				continue;
			}
			String path = fileItem.getName() ;
			fileSize = fileItem.getSize();
			fileName=(path.lastIndexOf("/")!=-1)?path.substring(path.lastIndexOf("/")+1):path;  //得到上传文件名
			fileType=path.substring(path.lastIndexOf(".")+1);  //文件类型
			fileAllPath=filePath+"/"+fileName;  //文件全路径
			relativeAllPath=filePath+"/"+fileName;  //文件相对路径
			
			System.out.println("文件全路径为-----:"+fileAllPath);
			
			if(fileName!=null&&!"".equals(fileName.trim())){
				File uploadFileFload = new File(filePath); 
				File uploadFile = new File(fileAllPath); 
				
				if(!uploadFileFload.isDirectory()){
					boolean falg = uploadFileFload.mkdirs();
					System.out.println("文件夹创建状态-----:"+falg);
				}else{
					System.out.println("文件保存在------:"+filePath);
				}
				fileItem.write(uploadFile);  //写入文件
				System.out.println("文件上传成功,文件名为: "+fileName+" 大小为: "+fileSize+"字节");
				
			}else{
				System.out.println("文件上传失败");
			}
		}
		
	    
	}

    方式一的心得:

 

    1.服务器端与客户端的编码要一致,否则上传包含有中文的文件的文件名会乱码。

    2.设置了缓存大小后,如果上传的文件大于缓存设置。则会先上传到临时文件夹,当调用write方法时才写入到指定路径中,以节省内存占用。

    3.上传文件夹要先创建好,然后再写入文件。这个是容易忽略的。

    4.在springMVC等框架中,parseRequest返回的结果如果为空,则是框架已经对对包含了文件输入流的requet进行了处理。我们得到的已经不是原始的request,所以变会为空了。笔者在使用第一种方法的时候就遇到这个问题,遂使用方式二。

 

方式二、使用springMVC的文件上传

    实际上spingMVC对request的解析也是用common-fileupload中的parseRequest方法,这也就是方式一中parseRequest为空的原因。spingMVC已经帮我们处理了。

    首先我们需要现在application-content.xml中添加该类,使用该类处理后,与上传相关的设置是在xml中配置的。

   

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

    之后的处理就比较简单了,以下是实现。

public  List<Map<String,String>> mvcFileUpload(HttpServletRequest request, String fload) throws IllegalStateException, IOException{
		Date currData = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String classPath=this.getClass().getClassLoader().getResource("").getPath();
        String projectPath=classPath.substring(0, classPath.length()-"/WEB-INF/classes/".length());
        String projectName=projectPath.substring(projectPath.lastIndexOf("/")+1);
        String filePath=projectPath+fload+"/"+sdf.format(currData);  //文件夹存放路径
        String relativePath="/"+projectName+fload+"/"+sdf.format(currData); //文件夹存放相对路径
        String fileAllPath=null;     //文件存放路径
        String relativeAllPath=null;   //文件存放相对路径
        
        System.out.println("文件存放的文件夹为----:"+filePath);
        System.out.println("文件存放的文件夹相对路径为----:"+relativePath);
        
        File saveFolder = new File(filePath);
        if(!saveFolder.isDirectory()){
        	boolean falg = saveFolder.mkdirs();
        	System.out.println("文件夹创建状态-----:"+falg);
        }
		
        String realFileName=null;     //真实上传文件名
        String fileType=null;         //文件类型
        List<Map<String,String>> result=new ArrayList<Map<String,String>>();
        
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;  
		Iterator<String> fileNameIte = multipartRequest.getFileNames();
		while(fileNameIte.hasNext()){
			String fileName = fileNameIte.next();   
			MultipartFile mr = multipartRequest.getFile(fileName);
			
			realFileName = mr.getOriginalFilename();
			if(StringUtils.isNotBlank(realFileName)){
						
				System.out.println("上传的文件名为-----:"+realFileName);
			    fileType=realFileName.substring(realFileName.lastIndexOf(".")+1);
			    realFileName=realFileName.substring(0, realFileName.lastIndexOf("."))+"-"+System.nanoTime()+"."+fileType;  //对上传文件进行重命名
			    fileAllPath=filePath+"/"+realFileName;
			    relativeAllPath=relativePath+"/"+realFileName;
			    
				File localFile = new File(fileAllPath);
				mr.transferTo(localFile);
				
				Map<String, String> map = new HashMap<String, String>();
		        map.put("fileName", realFileName);
		        map.put("fileType", fileType);
		        map.put("fileAllPath", fileAllPath);
		        map.put("relativeAllPath", relativeAllPath);
		        
		        result.add(map);
			}
		}
		
		
        
        return result;
		
		
	}

 

 

    但笔者发现spingMVC处理的并不完善,当向相同路径重新上传相同文件名的文件时。会出现阻塞,可能是在处理的过程中没有关闭流,解决的办法就是对上传的每个文件进行重命名。

   

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics