spring boot + vue實現圖片上傳及展示


轉載:https://blog.csdn.net/weixin_40337982/article/details/84031778

   其中一部分對我很有幫助 轉載記錄下

 

首先,html頁面:

    <!--form中是要加這個enctype的-->
    <form class="form-horizontal" enctype="multipart/form-data">
     
    <div v-if="menu.type == 1" class="form-group">
        <div class="col-sm-2 control-label">圖片</div>
            <div class="col-sm-10">
            <div class="ui-upfile">
                    <div style="width: 150px;height: 140px;display:none;" class="file-area" />
                </div>
                <input type="hidden" name="menuImgUrl" class="menu-image-url" v-model="menu.menuImgUrl">
                <input type='button' class='btn' value='上傳圖片'οnclick="document.getElementById('file').click()" style=""/>
                <input type="file" class="menu-image-url" value=""  id="file"  @change="onUpload"  style="filter:alpha(opacity:0);opacity:0;width:0px">             
            </div>
        </div>
    </div>

 



這里要說明一下,由於使用的是vue,所有這里賦值取值都是使用v-model,然后這里為什么會有這么多input框,

第一個是返回我對象的屬性值的;

第二個是手寫的一個按鈕,因為如果直接使用input type=file的話,樣式比較丑,還會有未選擇文件那個字樣 ,可以那個type=file的input又是必須的。

所以這里我們使用一個button去覆蓋type=file的功能,並且把type=file的input隱藏起來,這里的核心代碼是:opacity:0;
        接下來,js代碼:

    onUpload(e){
                var files = e.target.files[0];
                var formFile = new FormData();
                formFile.append("file", files);
               $.ajax({
                    url: baseURL + 'sys/upload/uploadPic',//這里是請求后台的上傳文件接口
                    type: 'POST',
                    dataType: 'json',
                    cache: false,
                    data: formFile,
                    processData: false,
                    contentType: false,
                    success: function(r){    
                        
                        if (r.code === 0) {
                            vm.menu.menuImgUrl = r.fileUrl;
                            $(".file-area").css("display","block");
                            $(".file-area").html("<img src= '"+ r.fileUrl +"'>");
                        }else{
                            alert("文件上傳失敗:" + r.msg);
                        }
                    }
                });
            }

 




由於使用的是vue,所以這里是寫在methods下面的。

這里主要是請求后台,把文件傳過去,然后返回一個url,通過這個url我們可以直接訪問到圖片。
后台    UploadController類

@RestController
    @RequestMapping("/sys/upload")
    public class UploadController extends BaseController {
     
        
        /**
         * 上傳圖片
         * @param file
         * @param request
         * @throws IOException
         */
        @RequestMapping( value = "/uploadPic")
        @ResponseBody
        public R uploadPic(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request) throws IOException {
                    //目前這里是寫死的本地硬盤路徑
            String path = "D:/img";
            logger.info("path:" + path);
            //獲取文件名稱
            String fileName = file.getOriginalFilename();
            //獲取文件名后綴
            Calendar currTime = Calendar.getInstance();
            String time = String.valueOf(currTime.get(Calendar.YEAR))+String.valueOf((currTime.get(Calendar.MONTH)+1));
          //獲取文件名后綴
            String suffix = fileName.substring(file.getOriginalFilename().lastIndexOf("."));
            suffix = suffix.toLowerCase();
            if(suffix.equals(".jpg") || suffix.equals(".jpeg") || suffix.equals(".png")/* || suffix.equals(".gif")*/){
                fileName = UUID.randomUUID().toString()+suffix;
                File targetFile = new File(path, fileName);
                if(!targetFile.getParentFile().exists()){    //注意,判斷父級路徑是否存在
                    targetFile.getParentFile().mkdirs();
                }
                long size = 0;
                //保存
                try {
                    file.transferTo(targetFile);
                    size = file.getSize();
                } catch (Exception e) {
                    e.printStackTrace();
                    return R.error("上傳失敗!");
                }
                //項目url,這里可以使用常量或者去數據字典獲取相應的url前綴;
                String fileUrl="http://localhost:8080";
                //文件獲取路徑
                fileUrl = fileUrl + request.getContextPath() + "/img/" + fileName;
                logger.info("fileUrl:" + fileUrl);
                return R.ok().put("fileUrl", fileUrl);
            }else{
                return R.error("圖片格式有誤,請上傳.jpg、.png、.jpeg格式的文件");
            }
            
        }
    }

 


   

這里有個坑,就是由於spring boot使用的內置tomcat,所以會自動在系統盤下生成一個編譯路徑,大概是這樣的:

C:\Users\69223\AppData\Local\Temp\tomcat-docbase.6718506550492189172.8080


可是把文件放到這個下面,我們無法去正確獲取,而且這里的tomcat生成的文件夾中間那一段數字,還都是在變化的。具體原因沒有細究。

經過一天的百度及個人理解,最終決定使用映射;

在application.yml文件中添加要映射的絕對路徑,即圖片要保存的位置:

    #文件上傳
    cbs:
        imagesPath:
            file:/D:/img/

yml文件中格式要求極為嚴格 ,必須是4個空格,tab鍵不起作用,直接使用cbs.imagesPath.file也報錯。

這里的文件絕對路徑就是我們上傳文件時寫的上傳路徑;

之后編寫WebMvcConfig配置文件;

 

  @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter{
        
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/").setViewName("forward:/login.html");
            registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
            super.addViewControllers( registry );
        }
        
        /**
         * 在配置文件中配置的文件保存路徑
         */
        @Value("${cbs.imagesPath}")
        private String mImagesPath;
        
        @Bean
        public MultipartConfigElement multipartConfigElement(){
            MultipartConfigFactory factory = new MultipartConfigFactory();
            //文件最大KB,MB
            factory.setMaxFileSize("1024MB");
            //設置總上傳數據總大小
            factory.setMaxRequestSize("1024MB");
            return factory.createMultipartConfig();
        }
     
        /**
         * 這里是映射文件路徑的方法
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if(mImagesPath.equals("") || mImagesPath.equals("${cbs.imagesPath}")){
                String imagesPath = WebMvcConfig.class.getClassLoader().getResource("").getPath();
                if(imagesPath.indexOf(".jar")>0){
                    imagesPath = imagesPath.substring(0, imagesPath.indexOf(".jar"));
                }else if(imagesPath.indexOf("classes")>0){
                    imagesPath = "file:"+imagesPath.substring(0, imagesPath.indexOf("classes"));
                }
                imagesPath = imagesPath.substring(0, imagesPath.lastIndexOf("/"))+"/img/";
                mImagesPath = imagesPath;
            }
            registry.addResourceHandler("/img/**").addResourceLocations(mImagesPath);
            super.addResourceHandlers(registry);
        }
        
    }

addResourceHandlers()方法是映射文件路徑的方法;

這里我們還需要在權限配置類中添加如下,即放開img下的權限控制,否則會涉及到權限,被攔截;

filterMap.put("/img/**", "anon");


截止到這里,我們的上傳圖片基本已經完成了,接下來就可以進入測試階段。

我們把文件上傳到D盤下面的img文件夾,上傳成功之后,我們使用:

http://localhost:8080/項目名/img/3b13ad02-3812-4c39-880d-799172801284.png

就可以直接訪問到我們的圖片了。

項目得啟動起來。

只是基本的使用,具體的底層原理,並未深究。

點個贊吧!^_^ !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM