vue+springboot圖片上傳和顯示

一凡碼農 2020-02-14 14:39:02
一、前言

在使用spring boot做後台系統,vue做前端系統,給客戶開發一套系統時候,其中用到了圖片上傳和顯示的功能。

二、環境

前端:vue前端組件:tinymce後台:spring boot:2.2.3

三、正文

在客戶開發一套門戶管理系統時,集成了tinymce組件,用于編輯內容,springboot不同于其他項目。  是集成tomcat的,文件和圖片是不能直接訪問的。所以我在做集成富文本編輯器時,需要處理圖片的問題。這個問題跟上傳頭像等顯示圖片的功能是類似的。下面記錄詳情步驟代碼。

第一步:集成tinymce組件

<!--引入tinymce組件-->import Tinymce from '@/components/Tinymce'

<!--啓用tinymce組件--><el-form-item>    <el-button type="primary" :loading="btnLoading" @click="onSubmit" >保 存</el-button></el-form-item>

<!--核心代碼--><template>    <div class="page-container">        <div class="page-title-section">        </div>        <div class="page-content-section">            <div class="page-content-form">                <el-form ref="dataForm" :model="formData" :rules="formRules" label-width="180px">                    <el-form-item>                        <div>                            <tinymce v-model="formData.content" :height="300" />                        </div>                    </el-form-item>                    <el-form-item>                        <el-button type="primary" :loading="btnLoading" @click="onSubmit" >保 存</el-button>                    </el-form-item>                </el-form>            </div>        </div>    </div></template><script>import Tinymce from '@/components/Tinymce'export default {    name:"contentEdit",    components: {Tinymce},    data(){        return{            formData:{                content:'',            },        }    },    created() {    },    mounted() {},    activated() {},    deactivated() {},    methods:{        //表單提交        onSubmit(){            this.$refs['dataForm'].validate((valid) => {                if (valid) {                    this.btnLoading = true                    this.$axios({                        url: this.formData.id == '' ? '/products/save' : '/products/edit',                        method: 'POST',                        params: this.formData                    }).then(res => {                        //處理成功回調                        const{ state,result , errmsg} = res.data                        if( state && state == 1 ){                            this.$message.success('操作成功');                            this.$router.push( {path:'/products/list'} )                        }else{                            return this.$message.error(errmsg || '操作失敗');                        }                    }).finally(() => {                        this.btnLoading = false                    })                }            })        },</script>

<!--Tinymce初始化代碼-->initTinymce() {      const _this = this      window.tinymce.init({        selector: `#${this.tinymceId}`,        language: this.languageTypeList['en'],        height: this.height,        body_class: 'panel-body ',        object_resizing: false,        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,        menubar: this.menubar,        plugins: plugins,        end_container_on_empty_block: true,        powerpaste_word_import: 'clean',        code_dialog_height: 450,        code_dialog_width: 1000,        advlist_bullet_styles: 'square',        advlist_number_styles: 'default',        imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],        default_link_target: '_blank',        link_title: false,        nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin        //上傳圖片回調        images_upload_handler:(blobInfo, success, failure) => {             var xhr, formData;              xhr = new XMLHttpRequest();              xhr.withCredentials = false;              xhr.open('POST', '/api/file/imageUpload');              xhr.onload = function () {                  var json;                  if (xhr.status !== 200) {                      failure('HTTP Error: ' + xhr.status);                      return;                  }                  json = JSON.parse(xhr.responseText);                  // console.log(json);                  json.location = util.baseURL + json.data.filename; //在該位置,如果您的後端人員返回的字段已經包含json.location信息,則該處可以省略                  if (!json || typeof json.location !== 'string') {                  failure('Invalid JSON: ' + xhr.responseText);                      return;                  }                  success(json.location);              };              formData = new FormData();              formData.append('file', blobInfo.blob(), blobInfo.filename());            xhr.send(formData);        },        init_instance_callback: editor => {          if (_this.value) {            editor.setContent(_this.value)          }          _this.hasInit = true          editor.on('NodeChange Change KeyUp SetContent', () => {            this.hasChange = true            this.$emit('input', editor.getContent())          })        },        setup(editor) {          editor.on('FullscreenStateChanged', (e) => {            _this.fullscreen = e.state          })        }        // 整合七牛上傳        // images_dataimg_filter(img) {        //   setTimeout(() => {        //     const $image = $(img);        //     $image.removeAttr('width');        //     $image.removeAttr('height');        //     if ($image[0].height && $image[0].width) {        //       $image.attr('data-wscntype', 'image');        //       $image.attr('data-wscnh', $image[0].height);        //       $image.attr('data-wscnw', $image[0].width);        //       $image.addClass('wscnph');        //     }        //   }, 0);        //   return img        // },        // images_upload_handler(blobInfo, success, failure, progress) {        //   progress(0);        //   const token = _this.$store.getters.token;        //   getToken(token).then(response => {        //     const url = response.data.qiniu_url;        //     const formData = new FormData();        //     formData.append('token', response.data.qiniu_token);        //     formData.append('key', response.data.qiniu_key);        //     formData.append('file', blobInfo.blob(), url);        //     upload(formData).then(() => {        //       success(url);        //       progress(100);        //     })        //   }).catch(err => {        //     failure('出現未知問題,刷新頁面,或者聯系程序員')        //     console.log(err);        //   });        // },      })    },    destroyTinymce() {      const tinymce = window.tinymce.get(this.tinymceId)      if (this.fullscreen) {        tinymce.execCommand('mceFullScreen')      }      if (tinymce) {        tinymce.destroy()      }    },    setContent(value) {      window.tinymce.get(this.tinymceId).setContent(value)    },    getContent() {      window.tinymce.get(this.tinymceId).getContent()    },    imageSuccessCBK(arr) {      const _this = this      arr.forEach(v => {        window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)      })    }  }

第二步:後台代碼

@RequestMapping(value = "/imageUpload", method = RequestMethod.POST)    public void imageUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) {        try {            logger.info("上傳圖片名 :" + file.getOriginalFilename());            if (!file.isEmpty()) {//                Properties p = new Properties();// 屬性集合對象//                String path = RedisUtil.class.getClassLoader().getResource("").getPath()+"global.properties";//                FileInputStream fis = new FileInputStream(path);// 屬性文件輸入流//                p.load(fis);// 將屬性文件流裝載到Properties對象中//                fis.close();// 關閉流//                String uploadPath = p.getProperty("imgUpload.url");//                //路徑名稱上加上-年/月日:yyyy/MMdd//                uploadPath += "Uploads/"+new SimpleDateFormat("yyyy").format(new Date())+ "/" +new SimpleDateFormat("MMdd").format(new Date())+"/";                String path= request.getServletContext().getRealPath("/");path="/Users/qinshengfei/fsdownload";                logger.error("path:"+path);                //路徑名稱上加上-年/月日:yyyy/MMdd                String uploadPath = File.separatorChar+"Uploads"+File.separatorChar+new SimpleDateFormat("yyyy").format(new Date())+                        File.separatorChar +new SimpleDateFormat("MMdd").format(new Date())+File.separatorChar;                // 文件上傳大小                long fileSize = 10 * 1024 * 1024;                //判斷文件大小是否超過                if (file.getSize() > fileSize) {                    backInfo(response, false, 2, "");                    return;                }                //獲取上傳文件名稱                String OriginalFilename = file.getOriginalFilename();                //獲取文件後綴名:如jpg                String fileSuffix = OriginalFilename.substring(OriginalFilename.lastIndexOf(".") + 1).toLowerCase();                if (!Arrays.asList(TypeMap.get("image").split(",")).contains(fileSuffix)) {                    backInfo(response, false, 3, "");                    return;                }                //判斷是否有文件上傳//                if (!ServletFileUpload.isMultipartContent(request)) {//                    backInfo(response, false, -1, "");//                    return;//                }                // 檢查上傳文件的目錄                File uploadDir = new File(path+uploadPath);                System.out.println(path+uploadPath);                if (!uploadDir.isDirectory()) {                    if (!uploadDir.mkdirs()) {                        backInfo(response, false, 4, "");                        return;                    }                }                // 是否有上傳的權限                if (!uploadDir.canWrite()) {                    backInfo(response, false, 5, "");                    return;                }                // 新文件名-加13爲隨機字符串                String newname = getRandomString(13) +"." + fileSuffix;                File saveFile = new File(path+uploadPath, newname);                try {                    file.transferTo(saveFile);                    backInfo(response, true, 0, uploadPath+newname);                } catch (Exception e) {                    logger.error(e.getMessage(), e);                    backInfo(response, false, 1, "");                    return;                }            } else {                backInfo(response, false, -1, "");                return;            }        } catch (Exception e) {            logger.error(e.getMessage());        }    }    // 返回信息    private void backInfo(HttpServletResponse response, boolean flag, int message, String fileName) {        fileName=fileName.replace("\\","/");        String json = "";        if (flag) {            json = "{ \"status\": \"success";        } else {            json = "{ \"status\": \"error";        }        json += "\",\"fileName\": \"http://127.0.0.1:8090/file/show?fileName=" + fileName + "\",\"message\": \"" + message + "\"}";        try {            response.setContentType("text/html;charset=utf-8");            response.getWriter().write(json);        } catch (IOException e) {            logger.error(e.getMessage(), e);        }    }

第三步:後台處理顯示圖片

/**     * 顯示單張圖片     * @return     */    @RequestMapping("/show")    public ResponseEntity showPhotos(String fileName){        try {            String path = "/Users/qinshengfei/fsdownload";            // 由于是讀取本機的文件,file是一定要加上的, path是在application配置文件中的路徑            logger.error("showPhotos:"+path+fileName);            return ResponseEntity.ok(resourceLoader.getResource("file:" + path + fileName));        } catch (Exception e) {            return ResponseEntity.notFound().build();        }    }

第四步:顯示效果

總結

這個例子是工作中遇到的一個問題,這裏只講述tinymce組件圖片功能。同時,工作中使用使用到了vue-cropper組件,原理類似。

0 阅读:0

一凡碼農

簡介:專業分享開發技術知識