欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot+ajax实现多图上传及回显

程序员文章站 2024-01-20 10:20:34
...

多文件上传(主要是前端回显), 带表单数据

SpringBoot+ajax实现多图上传及回显

  • 后端文件上传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>&emsp;
                            <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;">&times;</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>
    

引入js以及样式在图片上传回显上未用到,可根据需要调整样式


相关标签: java js