项目中遇到上传图片的需求,简单记录一下实现逻辑
JSP+SSM
页面引入依赖
<link href="${ctxStatic}/plugins/bootstrap-fileinput/css/fileinput.css" media="all" rel="stylesheet" type="text/css"/>
<link href="${ctxStatic}/plugins/bootstrap-fileinput/themes/explorer-fas/theme.css" media="all" rel="stylesheet" type="text/css"/>
<link href="${ctxStatic}/plugins/bootstrap-fileinput/css/all.css" rel="stylesheet" crossorigin="anonymous"/>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/js/fileinput.js" type="text/javascript"></script>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/js/plugins/piexif.js" type="text/javascript"></script>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/js/plugins/sortable.js" type="text/javascript"></script>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/themes/fas/theme.js" type="text/javascript"></script>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/themes/explorer-fas/theme.js" type="text/javascript"></script>
<script src="${ctxStatic}/plugins/bootstrap-fileinput/js/locales/zh.js" type="text/javascript"></script>
编写选择文件的div
<div class="from-group">
//vo.photo为后端实体类的照片属性,String类型
<input type="hidden" id="files" value='${vo.photo}'/>
<div class="col-md-6 col-sm-12 col-xs-12">
<label class="col-sm-4 col-xs-2 control-label">照片:</label>
<div class="col-sm-8 col-xs-4">
<input id="uplodaFlie" name="uploadFile" type="file" multiple>
</div>
</div>
</div>
编写script代码块
<script type="text/javascript">
var uplodaFlie='';
var showBrowse = false; //选择文件按钮
var actionDelete = ''//删除按钮
$(document).ready(function () {
uplodaFlie = $("#uplodaFlie");
showBrowse = true;
actionDelete = '<button type="button" class="kv-file-remove {removeClass}" title="{removeTitle}"{dataUrl}{dataKey}>{removeIcon}</button>';
hxfiles();
var btns = '<button type="button" class="file-download btn btn-sm btn-kv btn-default btn-outline-secondary" title="下载文件" data-filename="{caption}" "{dataKey}">' +
'<i class="fas fa-download"></i>' +
'</button>';
uplodaFlie.fileinput({
theme: 'fas',
language: 'zh',
//uploadUrl: '#',
showBrowse:showBrowse,
showRemove : true, //显示移除按钮
showPreview : true, //是否显示预览
showCaption: false,//是否显示标题
showUpload:false, //是否显示文件上传按钮
browseClass: "btn btn-primary", //按钮样式
dropZoneEnabled: false,//是否显示拖拽区域
maxFileCount: 8, //表示允许同时上传的最大文件个数
enctype: 'multipart/form-data',
validateInitialCount:true,
overwriteInitial: false,//是否在上传下一个文件的时候覆盖前一个
initialPreviewAsData: true,//实现初始化预览
removeFromPreviewOnError:true,//碰到上传错误的文件,不显示在框内
allowedFileExtensions: ["gif","png","jpeg","jpg"],
initialPreviewShowDelete:true,
layoutTemplates:{
actionUpload:'', //设置为空可去掉上传按钮
actionDelete:actionDelete, //设置为空可去掉删除按钮
},
initialPreview: initialPreview,
initialPreviewConfig: initialPreviewConfig,
otherActionButtons: btns,
});
$('.file-download').on('click', function() {
console.log(this);
var $btn = $(this)
, key = $btn.data('key')
, fileName = $btn.data('filename');
var url = '${fastDFSUrl}'+key;
downLoadFile(url,fileName);
});
function downLoadFile(url,fileName) {
var x=new XMLHttpRequest();
var resourceUrl = url;
x.open("GET", resourceUrl, true);
x.responseType = 'blob';
x.onload=function(e){
// ie10+
if (navigator.msSaveBlob) {
var name = resourceUrl.substr(resourceUrl.lastIndexOf("/") + 1);
return navigator.msSaveBlob(x.response, name);
} else {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement('a');
a.href = url;
a.download = fileName;
a.click();
}
}
x.send();
}
//$("#name").focus();
//inputForm为文件上传div所在的form表单,此为from表单的提交方法
$("#inputForm").validate({
submitHandler: function (form) {
loading('正在提交,请稍等...');
form.submit();
},
errorContainer: "#messageBox",
errorPlacement: function (error, element) {
$("#messageBox").text("输入有误,请先更正。");
if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
error.appendTo(element.parent().parent());
} else {
error.insertAfter(element);
}
}
});
});
//回显附件
var initialPreview = [];
var initialPreviewConfig = [];
function hxfiles() {
var json = $("#files").val();
if(json){
var files = JSON.parse(json);
var id = $('#id').val();
for (var i = 0; i < files.length; i++) {
initialPreview.push('${fastDFSUrl}'+files[i].newName);
var row = {};
row.caption = files[i].oldName;
row.type = fileinput.checkFileType(files[i].oldName);
row.url = "${ctx}/deleteFile?id="+id;
row.key = files[i].newName;
row.width = "120px";
initialPreviewConfig.push(row)
}
}
}
</script>
后端Controller层保存方法绑定文件参数,编写删除文件的接口
@RequiresPermissions("oameetingroom:oaMeetingRoom:edit")
@RequestMapping(value = "save")
public String save(Entity entity, @RequestParam("uploadFile") MultipartFile[] uploadFiles, Model model, RedirectAttributes redirectAttributes) {
if (!beanValidator(model, entity)){
return form(entity, model);
}
entityService.save(entity,uploadFiles);
addMessage(redirectAttributes, "保存成功");
return "redirect:"+Global.getAdminPath()+"/list/?repage";
}
/**
* 删除文件服务器上的文件
* @param id
* @param key
* @return
*/
@RequestMapping(value = "deleteFile")
@ResponseBody
public String deleteFile(String id,String key) {
if(StringUtils.isBlank(key) || StringUtils.isBlank(id)){
return MessageUtil.sendFailMessage("参数错误");
}
return entityService.deleteFile(id,key);
}
编写Service层保存方法和删除文件方法
@Transactional(readOnly = false)
public void save(Entity entity, MultipartFile[] uploadFiles) {
ObjectMapper objectMapper = new ObjectMapper();
//上传文件到文件服务器
try {
ArrayList<HashMap<String, String>> list = new ArrayList<>();
if(StringUtils.isNotBlank(entity.getId())){
entity entity1 = entityDao.get(entity.getId());
if(entity1 != null && StringUtils.isNotBlank(entity1.getPhoto())){
String files = StringEscapeUtils.unescapeHtml4(entity1.getPhoto());
list = objectMapper.readValue(files,new TypeReference<List<HashMap<String, String>>>() { });
}
}
for (int i = 0; i < uploadFiles.length; i++) {
HashMap<String, String> map = new HashMap<>();
// 获取文件名
String fileName = uploadFiles[i].getOriginalFilename();
if(StringUtils.isBlank(fileName)){
continue;
}
// 获取文件后缀
String prefix=fileName.split("\\.")[1];
byte[] bytes = uploadFiles[i].getBytes();
String newName = FastDFSUtils.UploadByte(bytes, prefix);
if(StringUtils.isNotBlank(newName)){
map.put("oldName",fileName);
map.put("newName",newName);
list.add(map);
}
}
String writeValueAsString = objectMapper.writeValueAsString(list);
String files2 = StringEscapeUtils.unescapeHtml4(writeValueAsString);
oaMeetingRoom.setPhoto(files2);
} catch (Exception e) {
e.printStackTrace();
}
super.save(entity);
}
@Transactional(readOnly = false)
public String deleteFile(String id, String fileName) {
Entity entity = dao.get(id);
if(entity == null){
return MessageUtil.sendFailMessage("未找到要删除的数据");
}
try {
ObjectMapper objectMapper = new ObjectMapper();
if(StringUtils.isNotBlank(entity.getPhoto())){
String files = StringEscapeUtils.unescapeHtml4(entity.getPhoto());
ArrayList<HashMap<String, String>> list = objectMapper.readValue(files,new TypeReference<List<HashMap<String, String>>>() { });
for (int i = 0; i < list.size(); i++) {
HashMap<String, String> map = list.get(i);
if(map.get("newName").equals(fileName)){
list.remove(i);
}
}
String writeValueAsString = objectMapper.writeValueAsString(list);
String files2 = StringEscapeUtils.unescapeHtml4(writeValueAsString);
oaMeetingRoom.setPhoto(files2);
super.save(entity);
}
FastDFSUtils.deleteFile(Global.getConfig("STR_FILE_URL_P1"),fileName);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
//try catch 中的事物回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return MessageUtil.sendFailMessage("删除失败");
}
return MessageUtil.sendSuccessMessage();
}
数据库photo为vacher类型
封装好的工具类
import com.monistar.znhsmsai.common.config.Global;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.io.File;
import java.io.IOException;
public class FastDFSUtils {
public static String configFilePath;
static{
try {
if(null == configFilePath){
configFilePath = new File(FastDFSUtils.class.getResource("/").getFile()).getCanonicalPath() + File.separator + "monistar.properties";
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static String UploadByte(byte[] file_buff,String strSuffix) throws Exception{
String returnCode = "";
if(null == configFilePath){
configFilePath = new File(FastDFSUtils.class.getResource("/").getFile()).getCanonicalPath() + File.separator + "monistar.properties";
}
ClientGlobal.init(configFilePath);
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
NameValuePair[] meta_list = new NameValuePair[3];
meta_list[0] = new NameValuePair("width", "120");
meta_list[1] = new NameValuePair("heigth", "120");
meta_list[2] = new NameValuePair("author", "gary");
String[] results = storageClient.upload_file(Global.getConfig("STR_FILE_URL_P1"),file_buff, strSuffix, meta_list);
if (results == null){
return null;
}
String remote_filename = results[1];
returnCode = remote_filename;
trackerServer.close();
return returnCode;
}
public static FileInfo getFileInfo(String group_name,String remote_filename) throws Exception {
if(null == configFilePath){
configFilePath = new File(FastDFSUtils.class.getResource("/").getFile()).getCanonicalPath() + File.separator + "monistar.properties";
}
ClientGlobal.init(configFilePath);
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
FileInfo info = storageClient.get_file_info(group_name, remote_filename);
trackerServer.close();
return info;
}
public static void deleteFile(String group_name,String remote_filename) throws Exception {
if(null == configFilePath){
configFilePath = new File(FastDFSUtils.class.getResource("/").getFile()).getCanonicalPath() + File.separator + "monistar.properties";
}
ClientGlobal.init(configFilePath);
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
storageClient.delete_file(group_name, remote_filename);
trackerServer.close();
}
}