加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bootstrap fileinput 使用记录

发布时间:2020-12-17 20:50:09 所属栏目:安全 来源:网络整理
导读:第一次使用bootstrap fileinput碰到了许多坑,做下记录 需求 本次使用bootstrap fileinput文件上传组件,主要用来上传和预览图片。作为一个后台管理功能,为某个表的某个字段,设置1对n的图片记录 网上搜索相关文章大多是一个简单的上传功能,对图片文件预览

第一次使用bootstrap fileinput碰到了许多坑,做下记录

需求

  1. 本次使用bootstrap fileinput文件上传组件,主要用来上传和预览图片。作为一个后台管理功能,为某个表的某个字段,设置1对n的图片记录
  2. 网上搜索相关文章大多是一个简单的上传功能,对图片文件预览显示,前后端交互并没多少详细描述

实现功能

  1. 后台界面例子

  1. 在新增和编辑里,需要添加图片上传显示需求,在这里我设置的字段名以_img结尾的图片都会在编辑新增里显示bootstrap fileinput组件

  1. 点击选择,选择文件后会变成一下情况

多出个上传按钮,图片也会多几个按钮,我选择了删除和放大图片的按钮,还可以显示图片单独上传按钮,这里我把它去掉了,统一在下方点击上传时,全部上传。==这里重点说下,我选择的异步上传方式,选择多个图片,上传后台组件采用的是多个图片轮询一张一张上传==

  1. 点击放大按钮

  2. 点击删除按钮,会调用删除方法,点击上传按钮,显示如下:

  3. 若本来就保存了图片,在点击修改的时候,我需要回显图片,显示如下

在没有继续上传图片的时候,它不会显示上传按钮,图片左下角小图标会有所变化

  1. 点击保存后

  2. 以上为需要实现的具体需求,下面分析代码

问题和解决方案

前端

  1. 此处只列出关键代码
    html:
<#elseif modifyField["field_name"]?ends_with("_img")?string == "true">
    <div class="form-group">
        <label class="control-label">${modifyField["field_description"]}:</label>
        <!-- 用来作为form表单提交上传图片返回id的集合,这里我采用`,`隔开的字符串形式保存 -->
        <input type="text" hidden id="${modifyField["field_name"]}" name="${modifyField["field_name"]}" value=""/>
        <!-- 用来初始化上传组件 -->
        <input type="file" name="file" id="${modifyField["field_name"]}_uploadfile" multiple="multiple" class="file-loading" />
    </div>
<#else>

js:

/**
 * 销毁图片上传组件
 * @param initUrl
 */
function destroyUploadImg(){
    //这里我用jquery找到我约定的上传组件,使用_uploadfile结尾,并遍历销毁
    $("#dlg input[id$=‘_uploadfile‘]").each(function(index,html){
        var upfile = $(html);
        upfile.fileinput("destroy");
    });
}

/**
 * 初始化fileinput组件
 */
var getFileInput = function(){
    //初始化方法,同样找到约定组件遍历
    $("#dlg input[id$=‘_uploadfile‘]").each(function(index,html){
        var upfile = $(html);

        var imgId = upfile.attr("id").substring(0,upfile.attr("id").lastIndexOf("_"))
        var val = $("#"+imgId).val();
        var preImageList = val.split(",");

        var initialPreview = [];
        var initialPreviewConfig = [];
        for (var i = 0; i < preImageList.length; i++) {
            if(preImageList[i] === "") {
                preImageList.splice(i,1);
                continue
            }
            initialPreview.push("${request.contextPath}/showPic?image_id=" + preImageList[i] + "&count=" + Math.random())

            var previewConfig = new Object();
            previewConfig.url = "${request.contextPath}/deleteImg.do";
            previewConfig.key = preImageList[i];

            var imageId = preImageList[i];
            previewConfig.extra = {"image_id": imageId,"pRow":JSON.stringify(pRow),"currPageId":${curr_page_id},"updateCol":imgId};//上传的额外参数,会作为post请求参数提交
            initialPreviewConfig.push(previewConfig);
        }
        if(upfile.length > 0) {
            //元素存在时执行的代码
            upfile.fileinput({
                theme: ‘fa‘,allowedFileExtensions: [‘jpg‘,‘png‘,‘gif‘],//接收的文件后缀
                //        maxFileSize:0,language: ‘zh‘,//设置语言
                uploadUrl: "${request.contextPath}/uploadImg.do",//上传的地址
                uploadAsync: true,//默认异步上传
                uploadExtraData:{"currPageId":${curr_page_id},"colName":imgId},//上传额外的post请求参数
//                showUpload: false,//是否显示上传按钮
                showRemove : false,//显示移除按钮
                showPreview : true,//是否显示预览
                showCaption: false,//是否显示标题
                browseClass: "btn btn-primary",//按钮样式
                dropZoneEnabled: true,//是否显示拖拽区域
                maxFileCount: 10,//表示允许同时上传的最大文件个数
                enctype: ‘multipart/form-data‘,validateInitialCount:true,overwriteInitial: false,//是否在上传下一个文件的时候覆盖前一个
                initialPreviewAsData: true,//实现初始化预览
                removeFromPreviewOnError:true,//碰到上传错误的文件,不显示在框内
                layoutTemplates:{
                    actionUpload:‘‘    //设置为空可去掉上传按钮
                    //actionDelete:‘‘  //设置为空可去掉删除按钮
                },initialPreview: initialPreview,//初始化预览文件的地址集合
                initialPreviewConfig:initialPreviewConfig//初始化预览文件配置
            }).on(‘filepreupload‘,function(event,data,previewId,index) {     //上传中
                var form = data.form,files = data.files,extra = data.extra,response = data.response,reader = data.reader;
                console.log(‘文件正在上传‘);
            }).on("fileuploaded",function (event,index) {    //一个文件上传成功
                console.log(‘文件上传成功!‘);
                if(data.response[‘result‘] === "success"){
                    var imageId = data.response[‘imageId‘];
                    preImageList.push(imageId);
                    var preImageStr = preImageList.join(",");
                    $("#"+imgId).val(preImageStr);
                }else{
                    return false;
                }
            }).on(‘fileerror‘,msg) {  //一个文件上传失败
                console.log(‘文件上传失败!‘);
            }).on(‘filesuccessremove‘,id) {
                console.log(‘文件删除‘);
            }).on(‘filedeleteerror‘,id) {
                console.log(‘文件删除错误‘);
            }).on(‘filedeleted‘,key,data) {
                //删除返回结果
                $("#"+imgId).val(data.responseJSON["imageIdStr"]);
                $(‘#dg‘).datagrid(‘reload‘);
            });
        }
    });
};

明白怎么回事,使用起来还是蛮简单的,就简单的两个创建和销毁方法,注释写的也蛮详细了,除了业务逻辑,组件的必要注释都在了

  1. 重点的地方
    • 文件上传只要填写上传地址和额外参数
    • 在fileuploaded方法中做上传完毕的业务逻辑
    • 文件删除只需要在预览配置里加上删除的地址和额外参数,新增的不管有没有上传的文件,删除的仅仅是前端
    • 在filedeleted方法中做删除完毕的业务逻辑

后端

  1. 先上代码段
/**
 * 显示图片
 * @param request
 * @return
 * @throws Exception
 */
@RequestMapping(value = {"/showPic.do","showPic"})
public ResponseEntity<byte[]> showPic(HttpServletRequest request) throws Exception {
    HashMap<String,Object> hashMap = this.getHashMap(request);
    String imageId = (String) hashMap.get("image_id");
    Map<String,Object> imgConditions = new HashMap<>();
    imgConditions.put("image_id",imageId);
    Map<String,Object> imgInfo = tableService.getRecord(Arrays.asList("image_path","uuid","image_type"),TableConstant.TB_IMG,imgConditions);
    String imageType = (String) imgInfo.get("image_type");
    String fullPath = imgInfo.get("image_path") + (String) imgInfo.get("uuid") + "." + imageType;

    FileInputStream inputStream = new FileInputStream(fullPath);
    int available = inputStream.available();
    byte[] data = new byte[available];
    inputStream.read(data);
    inputStream.close();
    HttpHeaders he = new HttpHeaders();
    he.setContentType(MediaType.valueOf("image/" + imageType));
    log.info("imageId:" + imageId + "读取");
    return new ResponseEntity<>(data,he,HttpStatus.OK);
}


/**
 * 上传图片
 * @param file
 * @return
 */
@RequestMapping(value = "/uploadImg.do")
public @ResponseBody
Map<String,Object> upload(HttpServletRequest request,@RequestParam("file") MultipartFile file) {
    HashMap<String,Object> hashMap = this.getHashMap(request);
    String originalFilename = file.getOriginalFilename();
    Map<String,Object> pRowMap = JSON.parSEObject(hashMap.get("pRow").toString(),Map.class);
    String colName = (String) hashMap.get("colName");
    Map<String,Object> result = new HashMap<>();
    result.put("result","fail");
    if (StringUtils.isNotEmpty(originalFilename)) {
        String[] splitFileName = originalFilename.split(".");
        String uuid = UUIDUtil.getUUID();
        Map<String,Object> rowMap = new HashMap<>();

        if (!StringUtils.isEmpty(originalFilename)) {
            splitFileName = originalFilename.split(".");
            String refPageId = (String) hashMap.get("currPageId");
            Map<String,Object> pageCondition2 = new HashMap<>();
            pageCondition2.put("page_id",refPageId);
            pageCondition2.put("del_flag",0);
            Map<String,Object> refPageInfo = tableService.getRecord(Arrays.asList("tb_name","primary_key"),TableConstant.TB_PAGE,pageCondition2);

            String tbName = (String) refPageInfo.get("tb_name");
            String[] tbNameSpl = tbName.split("_");
            String middlePath = tbNameSpl[tbNameSpl.length - 1];
            String filePath = sysconfig.getProperties().get("image.path") +
                    "/" + middlePath +
                    "/" + DateUtil.format2str("yyyyMMdd") +
                    "/";
            rowMap.put("image_type",splitFileName[splitFileName.length - 1]);
            rowMap.put("image_path",filePath);
            rowMap.put("uuid",uuid);
            rowMap.put("image_name",originalFilename);
            rowMap.put("page_id",refPageId);
            Long incr = redisService.incr(sysconfig.getProperties().get("sys.id") + "_primary_key_" + refPageInfo.get("tb_name") + "_" + refPageInfo.get("primary_key"),1);
            rowMap.put("image_id",incr);
            rowMap.put("col_name",colName);

            String primaryKey = (String) refPageInfo.get("primary_key");
            String pk = String.valueOf(pRowMap.get(primaryKey));
            rowMap.put("ref_value",pk);
            int ret = 0;
            try {

                ret = tableService.addRecord(TableConstant.TB_IMG,rowMap);
            } catch (Exception e) {
                String message = e.getMessage();
                if (message.contains("Duplicate entry")) {
                    log.info("主键冲突,redis刷新主键");
                    List<Map<String,Object>> recordsBySQL = tableService.getRecordsBySQL(String.format("select %s from %s order by %s desc limit 1","image_id","image_id"));
                    for (Map<String,Object> objectMap : recordsBySQL) {
                        redisService.set(sysconfig.getProperties().get("sys.id") + "_primary_key_" + TableConstant.TB_IMG + "_" + "image_id",String.valueOf(Integer.parseInt(objectMap.get("image_id").toString())));
                    }
                    incr = redisService.incr(sysconfig.getProperties().get("sys.id") + "_primary_key_" + TableConstant.TB_IMG + "_" + "image_id",1);
                    rowMap.put("image_id",incr);
                    ret = tableService.addRecord(TableConstant.TB_IMG,rowMap);
                }
            }

            if (ret > 0) {
                log.info(String.format("插入图片记录imageId:%s成功",incr));
                try {
                    boolean b = FileUtil.uploadFile(file.getBytes(),filePath,uuid + "." + splitFileName[1]);
                    if (b) {
                        log.info(String.format("插入图片imageId:%s成功",incr));
                        result.put("result","success");
                        result.put("imageId",incr);
                    } else {
                        log.info(String.format("插入图片imageId:%s失败",incr));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                log.info(String.format("插入图片记录imageId:%s失败",incr));
            }
        }

        return result;
    }

    return result;
}


/**
 * 图片删除
 */
@RequestMapping(value = "deleteImg.do")
@ResponseBody
public Map<String,Object> deleteImg(HttpServletRequest request) {
    Map<String,Object> data = new HashMap<>();
    HashMap<String,Object> hashMap = this.getHashMap(request);
    String imageId = (String) hashMap.get("image_id");
    String pageId = (String) hashMap.get("currPageId");
    String updateCol = (String) hashMap.get("updateCol");
    Map<String,Map.class);

    List<Map<String,Object>> records = tableService.getRecordsBySQL(String.format("select image_id,image_path,uuid,image_type from t_uls_image where image_id=%s",imageId));
    String imageIdStr = "";
    for (Map<String,Object> record : records) {
        String imagePath = (String) record.get("image_path");
        String uuid = (String) record.get("uuid");
        String imageType = (String) record.get("image_type");
        String path = imagePath + "/" + uuid + "." + imageType;
        File file = new File(path);
        if (file.exists()) {
            boolean delete = file.delete();
            if (delete) {
                log.info(String.format("图片imageId:%s删除成功",imageId));

                // 查找哪张表
                Map<String,Object> tableCondition = new HashMap<>();
                tableCondition.put("page_id",pageId);
                Map<String,Object> pageInfo = tableService.getRecord(Arrays.asList("tb_name",tableCondition);

                String tbName = (String) pageInfo.get("tb_name");
                String primaryKey = (String) pageInfo.get("primary_key");
                String pk = String.valueOf(pRowMap.get(primaryKey));
                List<Map<String,Object>> recordsBySQL = tableService.getRecordsBySQL(String.format("select %s from %s where %s=‘%s‘",updateCol,tbName,primaryKey,pk));
                for (Map<String,Object> objectMap : recordsBySQL) {
                    String o = String.valueOf(objectMap.get(updateCol));
                    String[] split = o.split(",");
                    List<String> strings = new ArrayList<>(Arrays.asList(split));
                    if(strings.contains(imageId)){
                        strings.remove(imageId);
                    }
                    imageIdStr = StringUtils.join(strings,",");
                }
                tableService.updateRecordsBySQL(String.format("update %s set %s=‘%s‘ where %s=‘%s‘",imageIdStr,pk));
            } else {
                log.info(String.format("图片imageId:%s删除失败",imageId));
            }
        }
    }
    data.put("data","success");
    data.put("imageIdStr",imageIdStr);
    return data;
}
  1. 后端和代码架构相关了,大致参考下,遇到的问题有
    • 已上传的图片有多张的情况,显示不正确,也就是同时请求后端显示图片的时候可能报各种异常,包括不知道哪来的NULLPointException
    • 之后发现,还是代码架构的问题,继承类把HttpServletRequest request封装成了全局变量,并从中取出了hashmap参数封装。导致在并发的时候,hashmap被覆盖
  2. 后端主要为框架设计的逻辑,和业务结合,根据实际情况编写,主要三大块,上传,读取,删除,问题不大

注意事项

  1. 上传和删除操作,后端返回的一定要是json数据,否则会解析错误,就算后台上传成功,前台也显示失败

参考API http://plugins.krajee.com/file-input

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读