springmvc-带预览的异步上传图片功能

2 篇文章 0 订阅
2 篇文章 0 订阅

依赖的环境: springmvc(详细配置不细说, 只说和上传有关的部分 ), jquery和相关的上传控件(点击下载, 不要积分)

 

后台部分:

springmvc 文件上传解析器配置(必须配置), IO异常配置(可选, 不是必须的)

 

<!-- 文件上传解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 默认编码 -->
		<property name="defaultEncoding">
			<value>UTF-8</value>
		</property>
		<property name="maxUploadSize">
			<!-- 最大1MB 1024*1024 -->
			<value>1048576</value>
		</property>
		<!-- 对上传的文件开启懒解析, controller中可以 -->
		<property name="resolveLazily" value="true" />
	</bean>

 	<!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->  
    <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->  
	<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->  
				<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_upload</prop>
			</props>
		</property>
	</bean>

 

controller中接收上传文件方法, 此处将文件统一保存到  项目/upload  目录下, 同时返回  uuid1.jpg!uuid2.png!     此种格式的字符串, 每个文件名用" ! " 分隔开, , 最后一个" ! " 不可少方便前台分割, 截取等操作.

 

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

/**
 * 文件处理控制器controller
 * 
 * @author yufu
 * @email ilxly01@126.com 2015-7-15
 */
@Controller
@RequestMapping(value = "/security/filegags")
public class FilegagsController {

	private static final Logger log = LoggerFactory
			.getLogger(FilegagsController.class);


	// 上传文件最大值
	@Value("${LoadUpFileMaxSize}")
	String LoadUpFileMaxSize;

	// 上传文件保存路径
	@Value("${uploadPath}")
	String uploadPath;

	/**
	 * 多文件上传接收方法
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, String> aadd_worker(
			MultipartHttpServletRequest multipartRequest,
			HttpServletResponse response) throws IOException {
		response.setContentType("text/html;charset=utf-8");
		String result = "success!";
		Map<String, String> map = new HashMap<String, String>();
		// 1-获取多个文件
		for (Iterator it = multipartRequest.getFileNames(); it.hasNext();) {
			// a-将读取到的单个文件保存到服务器的 uploadPath 路径下
			String key = (String) it.next(); // 文件名
			log.info("key: " + key);
			MultipartFile multipartFile = multipartRequest.getFile(key); // 根据key得到文件
			if (multipartFile.getOriginalFilename().length() > 0) {
				String originalFileName = multipartFile.getOriginalFilename();
				// b-截取后缀, 重命名文件, 使用uuid+后缀的方式命名保存到服务器上的文件
				String suffix = originalFileName.substring(originalFileName
						.lastIndexOf("."));
				log.info("文件后缀: " + suffix);
				// KitService.getUUID() 为自己写的自动生成一个UUID方法, 您可以自己写
				String fileName = KitService.getUUID() + suffix;
				log.info("新文件名: " + fileName);
				try {
					String uploadFileUrl = multipartRequest.getSession()
							.getServletContext().getRealPath(uploadPath);
					log.info("保存文件路径: " + uploadFileUrl);
					// c- 将文件保存到目标目录下
					File uploadFile = saveFileFromInputStream(
							multipartFile.getInputStream(), uploadFileUrl,
							fileName);
					if (uploadFile.exists()) {
						log.info(originalFileName + "上传成功");
					} else {
						log.info(originalFileName + "上传失败");
						throw new FileNotFoundException("file write fail: "
								+ fileName);
					}
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					log.info(originalFileName + "上传失败");
					e.printStackTrace();
				}
				result += fileName + Constants.STRING_SPILIT;
			}
		}
		// response.getWriter().write(result);
		map.put("notice", result);
		return map;
	}

	/**
	 * 上传图片超出最大值时, 弹出的异常
	 * 
	 * @param ex
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@ExceptionHandler(Exception.class)
	public void handlerException(Exception ex, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		response.setContentType("text/html;charset=utf8");
		String notice = "error";
		if (ex instanceof MaxUploadSizeExceededException) {
			notice = "文件大小不超过"
					+ getFileMB(((MaxUploadSizeExceededException) ex)
							.getMaxUploadSize());
		} else {
			notice = "上传文件出现错误,错误信息:" + ex.getMessage();
		}
		PrintWriter writer = response.getWriter();
		writer.write(notice);
	}

	/**
	 * 字节转为MB 方法
	 * 
	 * @param byteFile
	 * @return
	 */
	private String getFileMB(long byteFile) {
		if (byteFile == 0) {
			return "0MB";
		}
		long mb = 1024 * 1024;
		return "" + byteFile / mb + "MB";
	}

	// 保存文件到指定路径
	private File saveFileFromInputStream(InputStream stream, String path,
			String filename) {
		// 检查保存上传文件的文件夹是否存在
		File dirFile = new File(path);
		if (!dirFile.exists()) {
			dirFile.mkdir();
		}
		File file = null;
		FileOutputStream fs = null;
		try {
			file = new File(path + "/" + filename);
			fs = new FileOutputStream(file);
			byte[] buffer = new byte[1024 * 1024];
			int bytesum = 0;
			int byteread = 0;
			while ((byteread = stream.read(buffer)) != -1) {
				bytesum += byteread;
				fs.write(buffer, 0, byteread);
				fs.flush();
			}
			fs.close();
			stream.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (fs != null) {
					fs.close();
				}
				if (stream != null) {
					stream.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return file;
	}

}


前台部分:

 

html代码

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>自定义带缩略图的文件上传</title>
	<!-- 上传图片  begin, 可从本文章最顶部下载 -->
	<link rel="stylesheet" type="text/css" href="${contextPath}/js/lib/diyUpload/css/webuploader.css" />
	<link rel="stylesheet" type="text/css" href="${contextPath}/js/lib/diyUpload/css/diyUpload.css" />
	<!-- 此css样式在本页中 -->
	<link rel="stylesheet" type="text/css" href="${contextPath}/css/cs.css" />
	<script type="text/javascript" src="${contextPath}/js/jquery-1.8.0.min.js"></script>
	<script type="text/javascript" src="${contextPath}/js/lib/diyUpload/js/webuploader.html5only.min.js"></script>
	<script type="text/javascript" src="${contextPath}/js/lib/diyUpload/js/diyUpload.js"></script>
	<!-- 上传图片  end, 可从本文章最顶部下载 -->
	
	<!-- 此脚本为抽取出来的上传脚本, 可自定义. -->
	<script type="text/javascript" src="${contextPath}/js/lib/diyUpload/cs-belong.js"></script>
</head>
<body>
		<!-- 预览可能已经存在的图片的div -->
		执照扫描件:
		<div id="fileBlShow"></div>
		
		<!-- 上传按钮 -->
		<div id="fileBlUpload"></div>
		
		<!-- 保存实际图片名字符串的隐藏域 , value值是从后台传递过来的, 例如上文所说的   uuid1.jpg!uuid2.png!  此种格式的字符串, 每个文件名用" ! " 分隔开, 最后一个" ! " 不可少-->
		<input type="hidden" id="fileBl" name="fileBl" value="uuid1.jpg!uuid2.png!" />
		
		<!-- 遮罩层 大图显示图片div  begin -->
		<div id="bgDiv"></div>
		<div id="imgShowDiv"></div>
		<!-- 遮罩层 大图显示图片div  end -->

		<script type="text/javascript">
			$(document).ready(function(){
				//初始化可能已经存在的图片
				initImg('fileBlShow','${company.fileBl}','fileBl');
				
				
				//初始上传按钮
				initUploadfile('fileBlUpload','上传按钮','fileBl');
			});
		</script>
</body>
</html>

上述html中涉及到的cs.css和 cs-belong.js
cs.css

 

 

* {
	font-size: 14px;
}

body,input,textarea {
	font-family: 微软雅黑, helvetica, tahoma, verdana, sans-serif;
	padding: 0;
	margin: 0;
}

/**
 * 预览图片列表div样式
 **/
.preImgList{
	
}
.preImgList img{
	margin: 3px 5px;
	border: 2px solid rgb(108, 125, 247);
	padding: 4px;
	background: white;
}
/**
 * 弹出div窗口样式
 **/
#bgDiv{
	display: none;
	position: absolute;
	top: 0%;
	left: 0%;
	width: 100%;
	height: 100%;
	background-color: black;
	z-index: 1001;
	-moz-opacity: 0.7;
	opacity: .70;
	filter: alpha(opacity = 70);
}

#imgShowDiv{
	display: none;
	position: absolute;
	top: 1%;
	left: 1%;
	width: 95%;
	height: 93%;
	padding: 8px;
	border: 8px solid #E8E9F7;
	background-color: white;
	z-index: 1002;
	overflow: auto;
	text-align: center;
}
#imgShowDiv input{
	width: 50px;
	float: right;
	background-color: #358BFF;
	font-size: 16px;
	font-weight: bold;
	color: white;
}


cs-belong.js

 

 

/** 
 *	项目独有的 初始化上传空间, 图片显示, 删除等功能方法
 **/

/**
 * 初始化上传图片路径
 * id-按钮控件的id, 只所以加上这个参数, 是因为原来的项目中 一个页面有多个上传按钮存在的缘故
 * btnValue-上传按钮上的位子
 * return_input_id-返回的图片id放置的input控件id
 */
function initUploadfile(btnId,btnValue,returnInputId){
	$('#' + btnId).diyUpload({
		url: esd.common.server + 'security/filegags/upload',
		success:function( returndata ) {
			var data = returndata.notice;
			// 提取提示文字
			var notice = data.substring(0,data.indexOf('!'));
			if(notice == 'success'){
				var result = data.substring(data.indexOf('!') + 1);
				var preValue = $('#'+returnInputId).val();
				$('#'+returnInputId).val(preValue + result);
			}
		},
		error:function( err ) {
			alert('上传图片发生错误, 请刷新页面重新尝试, 或者联系管理员.');
		},
		buttonText : btnValue,
		chunked:true,
		// 分片大小
		chunkSize:512 * 1024,
		//最大上传的文件数量, 总文件大小,单个文件大小(单位字节);
		fileNumLimit:50,
		fileSizeLimit:500000 * 1024,
		fileSingleSizeLimit:50000 * 1024,
		accept: {}
	});
}

/**
 * 处理 存在的图片字符串, 分割, 并使之在前台显示出来~~
 * containerDiv-存放图片的div
 * filestr-取出来的图片名称组字符串, 其中是用 | 链接
 * filelistinput-图片文件名保存的隐藏input id
 **/
function initImg(containerDiv,filestr,filelistinput){
	// 分割字符串
	if(filestr == null || filestr == '' || filestr == undefined){
		return;
	}
	var fileNameArray = filestr.split('|');
	// 循环其中每个文件名, 组装成对应图片路径, 放到对应img的src中
	var content = '';
	$.each(fileNameArray,function(index,item){
		if(item == null || item == undefined || item == ''){
			
		}else{
			//图片, 单击查看, 双击删除
			content += '<img src="' + esd.common.server + 'upload/' + item + '" style="width:50px;" onmousedown="operateImg(event,this,\'' + filelistinput + '\')" />';
		}
	});
	$('#'+containerDiv).html(content).addClass('preImgList');
}

 
 /**
  * 图片点击事件, 左键查看, 右键删除
  **/
function operateImg(event,obj,filelistinput){
	// 右键
	if(event.button=='2'){  
		delImg(obj,filelistinput);
	}else{
	//左键
		showImg(obj); 
	}  
}

/**
 * 查看单张图片方法
 **/
function showImg(obj){
	var content = '<input type="button" value="关闭" onclick="hidediv()"/><br/><img src="' + $(obj).attr('src') + '" />';
	$('#bgDiv').show();
	$('#imgShowDiv').html(content).show();
}
/**
 * 删除单张图片方法
 **/
function delImg(obj,filelistinput){
	if(filelistinput == null  || filelistinput =='' || filelistinput == undefined){
		return;
	}
	if(!window.confirm('确实要删除该张图片么,此操作不可恢复, 点 “是” 继续删除, 点 “否” 取消。 ')){
		return;
	}else{
		//将对应的图片url从隐藏的input中删除
		// 1-取得图片名并加上 |
		var preurl = $(obj).attr('src');	//图片url
		var imgname = preurl.substring(preurl.lastIndexOf('/')+1) + '|'; //图片文件名
		// 2-从 隐藏input中 将imgname 删除掉~~
		var tt = $('#'+filelistinput).val();
		var targetvalue = $('#'+filelistinput).val().replace(imgname,'');
		// 3-新值赋给隐藏input
		$('#'+filelistinput).val(targetvalue);
		// 4-将该图片元素去除掉
		$(obj).remove();
	}
}

// 隐藏遮罩层
function hidediv() {
	$('#bgDiv').hide();
	$('#imgShowDiv').hide();
}

 

以上方法即是上传图片到服务器.  后续操作应该是 保存返回文件名的同时 也将服务器上保存的文件存储到数据库中( 此段代码未添加, 见谅)

 

有bug或者错误之处欢迎指正. 私信我即可.

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值