使用Spring MVC实现文件上传

一、单文件上传

Spring MVC中为文件上传提供了直接的支持,即MultipartResolver接口。
MultipartResolver 用于处理上传请求,将上传请求包装成可以直接获取文件的数据 ,从而方便操作。它有两个实现类:
StandardServletMultipartResolver -----使用了Servlet3.0标准的上传方式
CommonsMultipartResolver-------使用了Apache的commons-fileipload来完成上传

使用CommonsMultipartResolver完成文件上传的步骤

1、导入jar文件

  • commons-io-2.4.jar
  • commons-fileupload-1.2.2.jar

2、配置MultipartResolver

在Spring MVC配置文件中,使用CommonsMultipartResolver配置一个MultipartResolver(文件上传)解析器。

	<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="5000000"/>
		<property name="defaultEncoding" value="UTF-8"/>	
	</bean>

注:

  • defaultEncoding:请求的编码格式,默认为ISO-8859-1,此处设置为utf-8,
    defaultEncoding必须和jsp页面的pageEncoding设置一致,以便正确读取表单的内容。
  • maxUploadSize:上传文件的大小上限,单位为字节。

3、编写文件上传表单页

	<form id="userForm" name="userForm" method="post" 
            action="${pageContext.request.contextPath}/user/add.html"
            enctype="multipart/form-data">
	<div>
		图片: <input type="file" name="picPath" id="picPath"> 
	</div>
</form>

注: 负责文件上传的表单编码类型必须是"multipart/form-data"类型

4、编写控制器

Spring MVC会将上传文件绑定到MultipartFile对象中,MultipartFile提供了获取上传文件内容、文件名等,最后通过其transferTo()方法将文件存储到服务器上。

	/**
	 * 保存新增用户信息---单文件
	 * 
	 * @param user
	 * @param session
	 * @return
	 */

	@RequestMapping(value = "/addsave.html", method = RequestMethod.POST)
	public String addUserSave(User user, HttpSession session, HttpServletRequest request,
			@RequestParam(value = "picPath", required = false) MultipartFile attach) {

		String picPath= null; //保存到数据库的图片路径 
		//判断文件是否为空
		if (!attach.isEmpty()) {
			String path = request.getSession().getServletContext()
					.getRealPath("statics" + File.separator + "uploadfiles"); // 文件存放路径

			logger.info("uploadFile path========>" + path);

			String oldFileName = attach.getOriginalFilename(); // 原文件名
			logger.info("uploadFile oldFileName========>" + oldFileName);

			String prefix = FilenameUtils.getExtension(oldFileName); // 原文件后缀
			logger.info("uploadFile prefix========>" + prefix);

			int fileSize = 5000000;
			logger.debug("uploadFile size========>" + attach.getSize());

			// 上传大小不得超过500kb
			if (attach.getSize() > fileSize) {
				request.setAttribute("uploadFileError", "* 上传文件不得超过500kb!");
				return "useradd";
				// 判断上传格式是否正确
			} else if (prefix.equalsIgnoreCase("jpg") || prefix.equalsIgnoreCase("png")
					|| prefix.equalsIgnoreCase("jpeg") || prefix.equalsIgnoreCase("pneg")) {

				// 文件名称
				String fileName = System.currentTimeMillis() + new Random().nextInt(1000000) + "_Personal.jpg";
				logger.debug("new fileName=====" + attach.getName());

				File targetFile = new File(path, fileName);
				if (!targetFile.exists()) {
					targetFile.mkdirs();
				}
				 // 保存
				try {
					attach.transferTo(targetFile);
				} catch (Exception e) {
					request.setAttribute("uploadFileError", "*上传失败!");
					e.printStackTrace();
					return "redirect:/user/useradd.html";
				}
				picPath= path + File.separator + fileName;
			} else {
				request.setAttribute("uploadFileError", "*上传图片格式不正确!");
				return "redirect:/user/useradd.html";
			}
		}

		User u = (User) session.getAttribute("user"); // 获取当前用户
		user.setCreatedBy(u.getId()); // 创建者
		user.setCreationDate(new Date());
		// 创建日期
		user.setPicPath(picPath); // 设置图片路径
		logger.info("picPath============>" + picPath);
		try {
			// 判断是否添加成功,如果添加成功则跳转用户列表页
			if (userService.add(user) > 0) {
				logger.info("---------------=====>success");
				return "redirect:/user/userlist.html";
			}
		} catch (Exception e) {
			logger.info("---------------=====>error");
			e.printStackTrace();
		}
		return "redirect:/user/useradd.html";
	}

解析上传步骤:

  • (1)使用MultipartFile对象作为控制器处理方法的入参,从MultipartFile对象中可以获取上传文件的相关信息。

例:

@RequestParam(value="a_idPicPath",required=false) MultipartFile attach

注: 处理文件上传的请求方式一定是POST请求,GET请求无法处理文件上传。


(2)在处理方法体内,首先通过MultipartFile对象是否为空来判断是否有上传的文件,若不为空再进行处理,否则直接进行其他数据字段的保存。

例:

	if(!attach.isEmpty()){
		//上传操作
	}
	//调用userService.add(user)方法保存新增数据

(03)进行上传前的准备工作

  • 定义上传目标路径
	//文件存放路径
	String path=request.getSession().getServletContext().
			getRealPath("statics"+File.separator+"uploadfiles");	
  • 获取原文件名
	String oldFileName=attach.getOriginalFilename();	//原文件名
  • 获取原文件后缀,对后缀进行类型判断,若不匹配则给予提示
	String prefix=FilenameUtils.getExtension(oldFileName);	//原文件后缀
  • 获取原文件大小,与规定的上传大小进行比较,若超过规定大小,则给予提示。
	if(attach.getSize()>fileSize){	
		request.setAttribute("uploadFileError", "* 上传文件不得超过500kb!");
		return "useradd";
	}
  • 若满足以上规定(文件大小、文件后缀),则可以进行文件上传操作。首先定义新的文件名(当前系统时间+随机数+“_Personal.jpg”),以保证不会重复,并根据新的文件名+目标路径来创建一个File对象(该对象用来接收用户上传的文件流),若不存在,则自动创建。
	String fileName=System.currentTimeMillis()+new Random().nextInt(1000000)+"_Personal.jpg";	
	File targetFile=new File(path,fileName);
	if(!targetFile.exists()){
		targetFile.mkdirs();
	}
  • 然后调用MultipartFile对象的transferTo(targetFile)方法,把MultipartFile中文件流的数据输出到目标文件中。
	attach.transferTo(targetFile);
  • 将图片路径保存到数据库

二、多文件上传

实现多文件上传,只需要修改入参MultipartFile为数组,例

@RequestParam(value="attachs",required=false) MultipartFile[] attachs

在方法体内对该数组进行循环遍历,然后逐一步进行非空判断,从未进行文件上传操作。在多文件上传中, MultipartFile[] 数组里存放的文件对象,是按照Form表单的file标签顺序进行存储的,所以需要进行判断,并记录各自上传路径。

注:

  • 在多文件上传中,若入参对象MultipartFile为数组,则参数前必须要加上@RequestParam注解,否则会报错。
  • 若在多文件上传操作中入参对象为MultipartFile为数组,则多个file标签中的name属性值必须一致。
  • 多文件上传操作也可采用单独逐个入参,file标签的name属性值不同。

例:

@RequestMapping(value="/addsave.html",method=RequestMethod.POST)
public String addUserSave(User user,HttpSession session,HttpServletRequest request,
		@RequestParam(value="picPath1",required=false) MultipartFile picPath1,
		@RequestParam(value="picPath2",required=false) MultipartFile picPath2){
	
	//方法体省略,(分别进行两个文件的上传操作和数据库相应字段的更新)

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值