依赖的环境: 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或者错误之处欢迎指正. 私信我即可.