SpringBoot+ajax实现多图上传及回显
程序员文章站
2024-01-20 10:20:34
...
多文件上传(主要是前端回显), 带表单数据
-
后端文件上传Controller,返回boolean到前端,判断是否上传成功
/** * 添加商品 * * @param map * @return */ @PostMapping("/add.do") public boolean add(MultipartHttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> map) throws Exception { List<MultipartFile> files = request.getFiles("file"); //无文件时直接返回页面 if (files == null || files.isEmpty()) { request.getRequestDispatcher("toAdd.html").forward(request, response); } return productService.insert(map, files); }
-
Service层完成文件上传业务,生成新的文件名,添加图片信息到数据库后,再将文件存到指定目录,防止产生无效文件
public boolean insert(Map<String, Object> map, List<MultipartFile> files) { productMapper.insert(map); //获取新增物品的id int id = (int)map.get("id"); int image = 0; for (MultipartFile file : files) { //获取图片名 String fileName = file.getOriginalFilename(); //根据时间戳生成图片路径 String imageName = System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf(".")); Map<String, Object> photo = new HashMap<>(); photo.put("url", "/mall/images/"+imageName); photo.put("productId", id); photoMapper.insert(photo);//添加图片到数据库 image = (int)photo.get("id");//获取图片id try (InputStream stream = file.getInputStream()) { //根据路径生成文件 Files.copy(stream, Paths.get("E:/images/mall/"+imageName), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } } map.put("image", image); productMapper.update(map); return true; }
-
前端代码,thympleaf模板,使用ajax发送请求到数据库
<!DOCTYPE html> <html lang='cn' xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>添加商品</title> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/> <meta content="" name="description"/> <meta content="" name="author"/> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/bootstrap-responsive.min.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/font-awesome.min.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/style-metro.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/style.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/style-responsive.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/default.css}" rel="stylesheet" type="text/css" id="style_color"/> <link th:href="@{/css/uniform.default.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/pagination.css}" rel="stylesheet" type="text/css"/> <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap-fileupload.css}"/> <link rel="shortcut icon" th:href="@{/image/favicon.ico}"/> </head> <body > <div class="container-fluid"> <div class="row-fluid"> <h3 class="page-title"><i class="fa fa-shopping-bag"></i> 商品管理</h3> <ul class="breadcrumb"> <li> <a href="list.html"><i class="fa fa-home"></i>商品管理</a> <i class="fa fa-angle-right"></i> </li> <li> <a href="#">添加商品</a> </li> </ul> </div> <div class="row-fluid"> <div class="portlet box green"> <div class="portlet-title"> <div class="caption"> <i class="fa fa-reorder"></i> 添加商品 </div> </div> <div class="portlet-body"> <form id="myform" class="form-horizontal" enctype="multipart/form-data" method="post"> <div class="control-group"> <label class="control-label">商品名称:</label> <div class="controls"> <input name="title" type="text" class="m-wrap large"/> <span class="help-inline">name</span> </div> </div> <div class="control-group"> <label class="control-label">是否热门:</label> <div class="controls"> <select name="isHot" class="small m-wrap small"> <option value="1">是</option> <option selected="selected" value="0">否</option> </select> </div> </div> <div class="control-group"> <label class="control-label">市场价格:</label> <div class="controls"> <div class="input-prepend"> <span class="add-on">¥</span> <input name="marketPrice" type="text" class="m-wrap small"/> </div> <span class="help-inline">price</span> </div> </div> <div class="control-group"> <label class="control-label">商城价格:</label> <div class="controls"> <div class="input-prepend"> <span class="add-on">¥</span> <input name="shopPrice" type="text" class="m-wrap small"/> </div> <span class="help-inline">price</span> </div> </div> <div class="control-group"> <label class="control-label">所属二级分类:</label> <div class="controls"> <select name="csid" class="small m-wrap"> </select> </div> </div> <div class="control-group"> <label class="control-label">商品图片:</label> <div class="controls"> <input id="choose-file" style="position: absolute;opacity: 0;width: 150px;height: 150px;z-index: 200" multiple type="file" name="file" accept="image/gif,image/jpeg,image/x-png,image/png"/> <img th:src="@{/image/add.png}" style="width: 150px;z-index: 100"> <div class="file-list" style="display: inline-block;width: auto;position: relative;top: -30px;"> </div> <!-- 模态框(Modal),点击图片放大 --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-body"> <img id="imgSrc" src="" alt="" style="width: 570px;height: 570px;"/> </div> </div> </div> </div> </div> </div> <div class="control-group"> <label class="control-label">商品描述:</label> <div class="controls"> <textarea name="des" class="m-wrap large" rows="4"></textarea> </div> </div> <div class="form-actions"> <button type="submit" class="btn blue" onclick="doSave()"><i class="fa fa-check"></i>确定</button>  <button type="button" onclick="javascript:window.location.href='toList.html';" class="btn"><i class="fa fa-times"></i>返回 </button> </div> </form> </div> </div> </div> </div> <script th:src="@{/js/jquery-1.10.1.min.js}" type="text/javascript"></script> <script th:src="@{/js/jquery-migrate-1.2.1.min.js}" type="text/javascript"></script> <!-- IMPORTANT! Load jquery-ui-1.10.1.custom.min.js before bootstrap.min.js to fix bootstrap tooltip conflict with jquery ui tooltip --> <script th:src="@{/js/jquery-ui-1.10.1.custom.min.js}" type="text/javascript"></script> <script th:src="@{/js/bootstrap.min.js}" type="text/javascript"></script> <script th:src="@{/js/jquery.slimscroll.min.js}" type="text/javascript"></script> <script th:src="@{/js/jquery.blockui.min.js}" type="text/javascript"></script> <script th:src="@{/js/jquery.cookie.min.js}" type="text/javascript"></script> <script th:src="@{/js/jquery.uniform.min.js}" type="text/javascript"></script> <script type="text/javascript" th:src="@{/js/bootstrap-fileupload.js}"></script> <script th:src="@{/js/jquery.pagination.js}" type="text/javascript"></script> <script th:src="@{/js/app.js}" type="text/javascript"></script> <script> // <![CDATA[ $(function () { App.init(); //加载分类列表 $.ajax({ url: "../classification/list.do?type=2", type: "get", success: function (result) { if (result) { showData(result); } else { alert(result.message); } } }); }); function showData(data) { var select = $("[name='csid']"); if (!data || !data.length > 0) { return; } for (var i = 0; i < data.length; i++) { var option = $("<option></option>"); option.attr("value", data[i].id); option.text(data[i].cname); select.append(option); } } function doSave() { var formData = new FormData($("#myform")[0]) formData.delete("file"); for (var i=0;i<fileList.length;i++) { formData.append("file",fileList[i]); } $.ajax({ url : "add.do", data : formData, type : "post", dataType : "json", cache : false,//上传文件无需缓存 processData : false,//用于对data参数进行序列化处理 这里必须false contentType : false, //必须 success : function (resp) { if(resp.success){ location.href="/mall/admin/product/toList.html" }else{ alert("保存失败"); } } }); } /* * 图片上传 * */ //选择文件按钮 $file = $("#choose-file"); //回显的列表 $list = $('.file-list'); //选择要上传的所有文件 fileList = []; //当前选择上传的文件 var curFile; // 选择按钮change事件,实例化fileReader,调它的readAsDataURL并把原生File对象传给它,监听它的onload事件,load完读取的结果就在它的result属性里了。它是一个base64格式的,可直接赋值给一个img的src $file.on('change',function(){ //原生的文件对象(File对象数组),相当于$file.get(0).files[0]; curFile = this.files; //将curFile数组和FileList数组合并 fileList = fileList.concat(Array.from(curFile)); for(var i=0,len = curFile.length;i < len;i++){ reviewFile(curFile[i]) } }); //回显图片 function reviewFile(file){ //实例化fileReader, var fd = new FileReader(); //获取当前选择文件的类型 var fileType = file.type; //调它的readAsDataURL并把原生File对象传给它, fd.readAsDataURL(file);//base64 //监听它的onload事件,load完读取的结果就在它的result属性里了 fd.onload = function(){ $list.append('<label class="file-item" style="float: left"><img src="'+this.result+'" alt="" style="width: 120px;height: 120px;" οnclick="showImage(this)"/><i class="file-del" style="position: relative;left:-15px;top: -50px;color: red;">×</i></label>') } } //删除图片 $(".file-list").on('click','.file-del',function(){ var $parent = $(this).parent(); var index = $parent.index(".file-item"); //删除选择的图片 fileList.splice(index,1); $parent.remove(); }); //点击图片显示放大图(使用bootstrap的模态框) function showImage(e) { $("#imgSrc").attr("src",e.src); $('#myModal').modal('show'); } </script> </body> </html>