1.说明
本人在项目中使用的是springmvc+mybatis+spring框架下使用上传文件的功能,关键在于前端js和后台代码的理解和编写,代码不能单独拿来运行,是在理解的基础上,修改为适合自己开发环境的。
2.前端代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE HTML>
<html>
<head>
<jsp:include page="common/header.jsp"/>
<!--需要引入webuploader.css文件 -->
<link href="${pageContext.request.contextPath }/lib/webuploader/0.1.5/webuploader.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page-container">
<form method="post" class="form form-horizontal" id="form-goods-add">
<input name="id" type="hidden" value="${versioUpdate.id }" />
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk名字:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" readonly="readonly" value="${versionUpdate.apkName }" placeholder="" maxlength="100" name="apkName" id="apkName">
</div>
</div>
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk版本号:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" value="${versionUpdate.version }" placeholder="" maxlength="100" name="version">
</div>
</div>
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk简介:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" value="${versionUpdate.content }" placeholder="" maxlength="100" name="content">
</div>
</div>
<!-- apk上传文件 -->
<div class="row cl">
<input name="apkUrl" id="apkUrl" type="hidden" />
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk上传:</label>
<div class="btns" >
<!-- 这个picker是用来选择文件的 -->
<div id="picker" style="display:inline"></div>
<!-- 如果未使用自动上传,点击按钮可以触发上传事件 -->
<div id="ctlBtn" class="uploadbutton" ></div>
<!-- 存放需上传的文件信息-->
<div id="thelist" class="uploader-list"></div>
</div>
<!-- 上传文件的遮罩,本身未添加该div,因说到上传文件时,如果直接进行其他操作会有什么影响,因此添加遮罩和提示信息避免误操作-->
<div id="uploadbg"></div>
<!-- 文件上传时的提示信息处理,包含进度条等信息-->
<div id="uploadshow">
<font color='#EE7621'>
<label class="state" id="waitUpload">等待上传...</label>
</font>
<div class="progress" style="position: absolute;height:30px;width:300px;">
<p id="progressUpload" style="top:0px;position: absolute;transform: translate(0%,0%);font-size: 10px;height:15px;width:0px;background-color:#E0FFFF;text-align:center">0%
</p>
</div>
</div>
</div>
<div class="row cl">
<div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-2">
<button class="btn btn-primary radius" type="submit"><i class="Hui-iconfont"></i> 保存</button>
<button onClick="layer_close();" class="btn btn-default radius" type="button"> 取消 </button>
</div>
</div>
</form>
</div>
<jsp:include page="common/footer.jsp"/>
<!--请在下方写此页面业务相关的脚本-->
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/My97DatePicker/4.8/WdatePicker.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/jquery.validate.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/validate-methods.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/messages_zh.js"></script>
<!--需要引入webuploader.min.js文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/webuploader/0.1.5/webuploader.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/ueditor.config.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/ueditor.all.min.js"> </script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/lang/zh-cn/zh-cn.js"></script>
<style type="text/css">
/*上传文件的背景修饰 */
#uploadbg {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: #EBEBEB;
z-index: 1001;
-moz-opacity: 0.7;
opacity: .70;
filter: alpha(opacity = 70);
}
#uploadshow {
display: none;
position: absolute;
top: 45%;
left: 30%;
width: 40%;
height: 10%;
padding: 8px;
border: 0px solid #F1F1F1;
background-color: #F1F1F1;
z-index: 1002;
overflow: auto;
}
</style>
<script type="text/javascript">
/*********************************WebUpload 单文件上传 begin*****************************************/
//遮罩的方法
function showdiv() {
$('#uploadbg').css("display","block");
$('#uploadshow').css("display","block");
}
function hidediv() {
$('#uploadbg').css("display","none");
$('#uploadshow').css("display","none");
}
var $list = $("#thelist");//定义上传文件显示的位置
var fileSize = '';//获取文件大小
var lastModiDate = '';//获取文件最后修改日期
//初始化Web Uploader
var uploader = WebUploader.create({
swf: '${pageContext.request.contextPath }/lib/webuploader/0.1.5/Uploader.swf',//swf文件路径
server: "${pageContext.request.contextPath }/backend/common/uploadApkFile",// 文件接收后台路径。
pick: {
id: '#picker',
name:"multiFile", //这个地方 name 没什么用,虽然打开调试器,input的名字确实改过来了。但是提交到后台取不到文件。如果想自定义file的name属性,还是要和fileVal 配合使用。
label: '选择apk',
multiple:false //默认为true,true表示可以多选文件,HTML5的属性
},
formData: {//上传时提交自身需要的字段并传递到后台。
"status":"file",
"uploadNum":"0000004730",
"existFlg":'false'
},
fileVal:'multiFile',
resize: false,
auto:true ,//是否自动上传
threads:3,//上传并发数。允许同时最大上传进程数。
chunked: true, //分片处理
chunkSize: 10 * 1024 * 1024, //每片10M
accept: {// 只允许选择apk文件
title: 'apk文件',
extensions: 'apk'//允许的文件后缀
// mimeTypes: 'image/*'
},
//fileNumLimit:1,//最大选择要上传的文件总数
disableGlobalDnd: true // 禁掉全局的拖拽功能。
});
// //移除文件的方法,未进行后端删除的添加
// function deleFile(fileId) {
// uploader.removeFile(fileId,true);//调用方法删除文件队列
// $('#'+fileId).remove();//清理页面元素
// };
//上传按钮点击时触发
$("#ctlBtn").on("click", function() {
uploader.upload();
});
//当有文件添加进来的时候
uploader.on( 'fileQueued', function( file ) {
fileSize = file.size;//为文件大小赋值
// deleFile(file.id);
var timestamp = Date.parse(new Date(file.lastModifiedDate));
timestamp = timestamp / 1000;
lastModiDate = timestamp;//获取文件最后修改时间,并转换成时间戳
/* $list.append( '<div id="' + file.id + '" class="item" style="display:inline">' +
'<h4 class="info" style="display:inline">' + file.name + '</h4> <div class="uploadbutton" id=\'deleBut_'+file.id+'\' onclick="deleFile(\''+file.id+'\');" >移除</div>' +
'</div>' ); */// 在文件上传的位置添加文件信息,可以修改
showdiv();//因为设置的是自动上传,所以添加进来后,自动调用遮罩
});
//当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
uploader.on('uploadBeforeSend', function (obj, data, headers) {
data.lastModiDate = lastModiDate;//为formData赋值
data.fileSize = fileSize;
});
//文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$progress = $('#waitUpload');
$percent = $('#progressUpload');
$progress.text('正在上传,在此期间不要做其他操作,请耐心等待...');
$percent.css( 'width', percentage * 100 + '%' );
$percent.text((percentage * 100).toFixed(2) + '%');
});
//完成上传,不管成功或者失败,先把遮罩删除。
uploader.on( 'uploadComplete', function( file ) {
hidediv();
});
uploader.on("error", function (type) {
if (type == "Q_TYPE_DENIED") {
layer.msg("请上传apk格式文件");
}
});
// 文件上传成功之后进行的处理。
uploader.on( 'uploadSuccess', function( file ,data ) {
if(data.files){
//为input的id为apkUrl填充文件上传成功后返回文件的路径值和文件名
$("#apkUrl").val(data.files[0].url);
$("#apkName").val(data.files[0].fileName);
}
$success = $('#waitUpload');
$success.text('上传成功');
});
// 文件上传失败
uploader.on( 'uploadError', function( file ) {
$error = $('#waitUpload');
$error.text('上传失败');
});
//日期格式化成时间字符串
Date.prototype.format = function(fmt) {
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
};
/*********************************WebUpload 单文件上传 end*******************************************/
$(function(){
//表单验证
$("#form-goods-add").validate({
rules:{
apkName:{
required:true
},version:{
required:true
},content:{
required:true
}
},
onkeyup:false,
success:"valid",
submitHandler:function(form){
$(form).ajaxSubmit({url:'save',type:'POST',dataType:'JSON',success:function(data){
if(data.success){
var index = parent.layer.getFrameIndex(window.name);
parent.freshTable();
parent.layer.close(index);
}
}
});
return false;
}
});
});
</script>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE HTML>
<html>
<head>
<jsp:include page="common/header.jsp"/>
<!--需要引入webuploader.css文件 -->
<link href="${pageContext.request.contextPath }/lib/webuploader/0.1.5/webuploader.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page-container">
<form method="post" class="form form-horizontal" id="form-goods-add">
<input name="id" type="hidden" value="${versioUpdate.id }" />
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk名字:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" readonly="readonly" value="${versionUpdate.apkName }" placeholder="" maxlength="100" name="apkName" id="apkName">
</div>
</div>
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk版本号:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" value="${versionUpdate.version }" placeholder="" maxlength="100" name="version">
</div>
</div>
<div class="row cl">
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk简介:</label>
<div class="formControls col-xs-8 col-sm-9">
<input type="text" class="input-text" value="${versionUpdate.content }" placeholder="" maxlength="100" name="content">
</div>
</div>
<!-- apk上传文件 -->
<div class="row cl">
<input name="apkUrl" id="apkUrl" type="hidden" />
<label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>apk上传:</label>
<div class="btns" >
<!-- 这个picker是用来选择文件的 -->
<div id="picker" style="display:inline"></div>
<!-- 如果未使用自动上传,点击按钮可以触发上传事件 -->
<div id="ctlBtn" class="uploadbutton" ></div>
<!-- 存放需上传的文件信息-->
<div id="thelist" class="uploader-list"></div>
</div>
<!-- 上传文件的遮罩,本身未添加该div,因说到上传文件时,如果直接进行其他操作会有什么影响,因此添加遮罩和提示信息避免误操作-->
<div id="uploadbg"></div>
<!-- 文件上传时的提示信息处理,包含进度条等信息-->
<div id="uploadshow">
<font color='#EE7621'>
<label class="state" id="waitUpload">等待上传...</label>
</font>
<div class="progress" style="position: absolute;height:30px;width:300px;">
<p id="progressUpload" style="top:0px;position: absolute;transform: translate(0%,0%);font-size: 10px;height:15px;width:0px;background-color:#E0FFFF;text-align:center">0%
</p>
</div>
</div>
</div>
<div class="row cl">
<div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-2">
<button class="btn btn-primary radius" type="submit"><i class="Hui-iconfont"></i> 保存</button>
<button onClick="layer_close();" class="btn btn-default radius" type="button"> 取消 </button>
</div>
</div>
</form>
</div>
<jsp:include page="common/footer.jsp"/>
<!--请在下方写此页面业务相关的脚本-->
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/My97DatePicker/4.8/WdatePicker.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/jquery.validate.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/validate-methods.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/jquery.validation/1.14.0/messages_zh.js"></script>
<!--需要引入webuploader.min.js文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/webuploader/0.1.5/webuploader.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/ueditor.config.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/ueditor.all.min.js"> </script>
<script type="text/javascript" src="${pageContext.request.contextPath }/lib/ueditor/1.4.3/lang/zh-cn/zh-cn.js"></script>
<style type="text/css">
/*上传文件的背景修饰 */
#uploadbg {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: #EBEBEB;
z-index: 1001;
-moz-opacity: 0.7;
opacity: .70;
filter: alpha(opacity = 70);
}
#uploadshow {
display: none;
position: absolute;
top: 45%;
left: 30%;
width: 40%;
height: 10%;
padding: 8px;
border: 0px solid #F1F1F1;
background-color: #F1F1F1;
z-index: 1002;
overflow: auto;
}
</style>
<script type="text/javascript">
/*********************************WebUpload 单文件上传 begin*****************************************/
//遮罩的方法
function showdiv() {
$('#uploadbg').css("display","block");
$('#uploadshow').css("display","block");
}
function hidediv() {
$('#uploadbg').css("display","none");
$('#uploadshow').css("display","none");
}
var $list = $("#thelist");//定义上传文件显示的位置
var fileSize = '';//获取文件大小
var lastModiDate = '';//获取文件最后修改日期
//初始化Web Uploader
var uploader = WebUploader.create({
swf: '${pageContext.request.contextPath }/lib/webuploader/0.1.5/Uploader.swf',//swf文件路径
server: "${pageContext.request.contextPath }/backend/common/uploadApkFile",// 文件接收后台路径。
pick: {
id: '#picker',
name:"multiFile", //这个地方 name 没什么用,虽然打开调试器,input的名字确实改过来了。但是提交到后台取不到文件。如果想自定义file的name属性,还是要和fileVal 配合使用。
label: '选择apk',
multiple:false //默认为true,true表示可以多选文件,HTML5的属性
},
formData: {//上传时提交自身需要的字段并传递到后台。
"status":"file",
"uploadNum":"0000004730",
"existFlg":'false'
},
fileVal:'multiFile',
resize: false,
auto:true ,//是否自动上传
threads:3,//上传并发数。允许同时最大上传进程数。
chunked: true, //分片处理
chunkSize: 10 * 1024 * 1024, //每片10M
accept: {// 只允许选择apk文件
title: 'apk文件',
extensions: 'apk'//允许的文件后缀
// mimeTypes: 'image/*'
},
//fileNumLimit:1,//最大选择要上传的文件总数
disableGlobalDnd: true // 禁掉全局的拖拽功能。
});
// //移除文件的方法,未进行后端删除的添加
// function deleFile(fileId) {
// uploader.removeFile(fileId,true);//调用方法删除文件队列
// $('#'+fileId).remove();//清理页面元素
// };
//上传按钮点击时触发
$("#ctlBtn").on("click", function() {
uploader.upload();
});
//当有文件添加进来的时候
uploader.on( 'fileQueued', function( file ) {
fileSize = file.size;//为文件大小赋值
// deleFile(file.id);
var timestamp = Date.parse(new Date(file.lastModifiedDate));
timestamp = timestamp / 1000;
lastModiDate = timestamp;//获取文件最后修改时间,并转换成时间戳
/* $list.append( '<div id="' + file.id + '" class="item" style="display:inline">' +
'<h4 class="info" style="display:inline">' + file.name + '</h4> <div class="uploadbutton" id=\'deleBut_'+file.id+'\' onclick="deleFile(\''+file.id+'\');" >移除</div>' +
'</div>' ); */// 在文件上传的位置添加文件信息,可以修改
showdiv();//因为设置的是自动上传,所以添加进来后,自动调用遮罩
});
//当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
uploader.on('uploadBeforeSend', function (obj, data, headers) {
data.lastModiDate = lastModiDate;//为formData赋值
data.fileSize = fileSize;
});
//文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$progress = $('#waitUpload');
$percent = $('#progressUpload');
$progress.text('正在上传,在此期间不要做其他操作,请耐心等待...');
$percent.css( 'width', percentage * 100 + '%' );
$percent.text((percentage * 100).toFixed(2) + '%');
});
//完成上传,不管成功或者失败,先把遮罩删除。
uploader.on( 'uploadComplete', function( file ) {
hidediv();
});
uploader.on("error", function (type) {
if (type == "Q_TYPE_DENIED") {
layer.msg("请上传apk格式文件");
}
});
// 文件上传成功之后进行的处理。
uploader.on( 'uploadSuccess', function( file ,data ) {
if(data.files){
//为input的id为apkUrl填充文件上传成功后返回文件的路径值和文件名
$("#apkUrl").val(data.files[0].url);
$("#apkName").val(data.files[0].fileName);
}
$success = $('#waitUpload');
$success.text('上传成功');
});
// 文件上传失败
uploader.on( 'uploadError', function( file ) {
$error = $('#waitUpload');
$error.text('上传失败');
});
//日期格式化成时间字符串
Date.prototype.format = function(fmt) {
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
};
/*********************************WebUpload 单文件上传 end*******************************************/
$(function(){
//表单验证
$("#form-goods-add").validate({
rules:{
apkName:{
required:true
},version:{
required:true
},content:{
required:true
}
},
onkeyup:false,
success:"valid",
submitHandler:function(form){
$(form).ajaxSubmit({url:'save',type:'POST',dataType:'JSON',success:function(data){
if(data.success){
var index = parent.layer.getFrameIndex(window.name);
parent.freshTable();
parent.layer.close(index);
}
}
});
return false;
}
});
});
</script>
</body>
</html>
3.后端代码:
上传文件的核心代码:
package com.ie9e.framework.system.controller;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.ie9e.framework.common.constants.Global;
import com.ie9e.framework.common.controller.BaseController;
import com.ie9e.framework.system.entity.TSAttachment;
import com.ie9e.framework.system.model.FileMeta;
import com.ie9e.framework.system.service.AttachmentService;
import com.ie9e.framework.utils.ResourceUtil;
import net.coobird.thumbnailator.Thumbnails;
/**
* 通用业务处理
*
* @author 一叶扁舟(skiff)
*
*/
@Controller
@RequestMapping("${namespace.backend}/common")
public class CommonController extends BaseController {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(CommonController.class);
@Autowired
@Qualifier("attachmentService")
private AttachmentService attachmentService;
@RequestMapping("error/403")
public String e403() {
return PRE_BACK + "common/403";
}
@RequestMapping("error/404")
public String e404() {
return PRE_BACK + "common/404";
}
@RequestMapping("view/{id}")
public void getImageView(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id)
throws ServletException, IOException {
String url = attachmentService.getAttachmentWebUrl(id);
response.sendRedirect(url);
}
@RequestMapping("/upload")
@ResponseBody
public Map<String, Object> upload(MultipartHttpServletRequest request, HttpServletResponse response) {
Iterator<String> itr = request.getFileNames();
MultipartFile multipartFile = null;
LinkedList<FileMeta> files = new LinkedList<FileMeta>();
FileMeta fileMeta = null;
while (itr.hasNext()) {
multipartFile = request.getFile(itr.next());
if (files.size() >= 10) {
files.pop();
}
fileMeta = new FileMeta();
fileMeta.setFileName(multipartFile.getOriginalFilename());
fileMeta.setFileSize(multipartFile.getSize() / 1024 + " Kb");
fileMeta.setFileType(multipartFile.getContentType());
try {
TSAttachment attachment = attachmentService.saveAttachment(multipartFile);
// fileMeta.setBytes(multipartFile.getBytes());
fileMeta.setId(attachment.getId());
fileMeta.setUrl(attachmentService.getAttachmentWebUrl(attachment));
} catch (IOException e) {
e.printStackTrace();
}
files.add(fileMeta);
}
Map<String, Object> params = new HashMap<String, Object>();
params.put("files", files);
return params;
}
/**
* 方法功能说明:上传apk方法
* @参数: @param request
* @参数: @param response
* @参数: @return
* @return String
* @throws
*/
@RequestMapping("/uploadApkFile")
@ResponseBody
public Map<String, Object> uploadApkFile(MultipartHttpServletRequest request, HttpServletResponse response) {
Iterator<String> itr = request.getFileNames();
MultipartFile multipartFile = null;
LinkedList<FileMeta> files = new LinkedList<FileMeta>();
FileMeta fileMeta = null;
while (itr.hasNext()) {
multipartFile = request.getFile(itr.next());
if (files.size() >= 10) {
files.pop();
}
fileMeta = new FileMeta();
fileMeta.setFileName(multipartFile.getOriginalFilename());
fileMeta.setFileSize(multipartFile.getSize() / 1024 + " Kb");
fileMeta.setFileType(multipartFile.getContentType());
try {
//将apk文件上传到指定的文件夹中,然后返回该文件的路径
String pakUrl = uploadApkFileToFolder(multipartFile);
fileMeta.setUrl(pakUrl.replaceAll("\\\\", "/"));
String fileAllName = multipartFile.getOriginalFilename();
//文件后缀的长度
int extLength =getFileType(fileAllName).length();
//文件名,不带文件后缀的
String fileName = fileAllName.substring(0, fileAllName.length() - extLength - 1);
fileMeta.setFileName(fileName);
} catch (IOException e) {
e.printStackTrace();
}
files.add(fileMeta);
}
Map<String, Object> params = new HashMap<String, Object>();
params.put("files", files);
return params;
}
/**
* 方法功能说明: 将apk文件上传到服务器中的指定文件夹中
* @参数: @param file
* @参数: @param isThumb
* @参数: @param safety
* @参数: @return
* @参数: @throws IOException
* @return String
* @throws
*/
public String uploadApkFileToFolder(MultipartFile file) throws IOException {
String realFileName = file.getOriginalFilename();
String md5 = null;
//文件的后缀
String ext = getFileType(realFileName).toLowerCase();
long curTime = System.currentTimeMillis();
//String saveFileName = UUID.randomUUID().toString() + "." + ext;
//获取上传的文件夹路径,如果文件夹不存在就创建
String relativePath = getFileUploadPath(curTime) + realFileName;
String realPath = ResourceUtil.getSysPath()+ relativePath;
byte[] bts = file.getBytes();
File realFile = new File(realPath);
if(!realFile.getParentFile().exists()){
realFile.getParentFile().mkdirs();
}
//上传文件
FileUtils.writeByteArrayToFile(realFile, bts);
return relativePath;
}
/**
* 方法功能说明: 计算附件上传的路径
* @参数: @param datetime
* @参数: @param safety
* @参数: @return
* @return String
* @throws
*/
private static String getFileUploadPath(long datetime) {
Date date = new Date(datetime);
String dic = null;
dic = Global.UPLOAD_APK_VERSION_UPDATE_FOLDER + ResourceUtil.getSeparator() + DateFormatUtils.format(date, "yyyyMM");
File folder = new File(dic);
if (!folder.exists()) {
folder.mkdirs();
}
return dic + ResourceUtil.getSeparator();
}
/**
* 方法功能说明: 获取文件的后缀
* @参数: @param fileName
* @参数: @return
* @return String
* @throws
*/
public static String getFileType(String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
}
}
提交到后台保存数据到数据库:
package com.ie9e.framework.system.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.util.NumberUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.druid.Constants;
import com.github.pagehelper.Page;
import com.ie9e.framework.common.controller.BaseController;
import com.ie9e.framework.common.model.AjaxJson;
import com.ie9e.framework.common.model.PageQuery;
import com.ie9e.framework.system.entity.TSVersionUpdate;
import com.ie9e.framework.system.service.VersionUpdateService;
import com.ie9e.framework.utils.ResourceUtil;
import com.ie9e.framework.view.JSONTableView;
/**
* @类功能说明: 处理apk版本更新的控制类,以及apk文件上传的处理
* @作者: 一叶扁舟
* @创建时间:2018年1月23日 上午10:35:57
* @版本:V1.0
*/
@Controller
@RequestMapping("${namespace.backend}/versionupdate")
public class VersionUpdateController extends BaseController {
private Logger logger = Logger.getLogger(VersionUpdateController.class);
@Autowired
@Qualifier("versionUpdateService")
private VersionUpdateService versionUpdateService;
@RequestMapping
public String versionupdate(HttpServletRequest request) {
return PRE_BACK + "version-update-list";
}
@RequestMapping("list")
public JSONTableView list(TSVersionUpdate versionUpdate, PageQuery pageQuery) {
Page<TSVersionUpdate> listPage = (Page<TSVersionUpdate>) versionUpdateService.listPage(versionUpdate, pageQuery);
return new JSONTableView(pageQuery, listPage);
}
@RequestMapping("del")
@ResponseBody
public AjaxJson del(Long id) {
AjaxJson ajaxJson = new AjaxJson();
try {
versionUpdateService.delVersionUpdate(id);
ajaxJson.setMsg("删除成功");
} catch (Exception e) {
ajaxJson.setCode("999");
ajaxJson.setMsg("删除失败");
}
return ajaxJson;
}
@ResponseBody
@RequestMapping(value = "save")
public AjaxJson save(TSVersionUpdate versionUpdate) {
AjaxJson ajaxJson = new AjaxJson();
boolean flag=false;
try {
//新增apk版本更新信息
if (versionUpdate.getId() == null) {
flag=true;
versionUpdate.setCreateDate(new Date());
Long userId = ResourceUtil.getUserId();
versionUpdate.setCreateId(userId);
versionUpdateService.addVersionUpdate(versionUpdate);
ajaxJson.setMsg("新增apk版本成功");
} else {
versionUpdateService.editVersionUpdate(versionUpdate);
ajaxJson.setMsg("编辑apk版本成功");
}
} catch (Exception e) {
e.printStackTrace();
ajaxJson.setSuccess(false);
if(flag){
ajaxJson.setMsg("新增apk版本失败");
}else{
ajaxJson.setMsg("编辑qpk版本失败");
}
}
return ajaxJson;
}
/**
* 方法功能说明: 对外接口,以json格式返回最新apk版本信息,包括apk版本,apk名字,apk访问的url
* @参数: @return
* @return String
* @throws
*/
@RequestMapping("getNewestApkVersion")
@ResponseBody
public String getNewestApkVersion(){
String result = versionUpdateService.getNewestApkVersion();
//result = result.replaceAll("\\", "");
return result;
}
@RequestMapping("edit")
public String edit(TSVersionUpdate versionUpdate,HttpServletRequest request) {
if (versionUpdate.getId() != null) {
versionUpdate = versionUpdateService.getbyId(versionUpdate.getId());
request.setAttribute("versionUpdate", versionUpdate);
}
return PRE_BACK + "version-update-edit";
}
}
4.效果截图: