zoukankan      html  css  js  c++  java
  • 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=" 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;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:Users69223AppDataLocalTemp	omcat-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

    就可以直接访问到我们的图片了。

    项目得启动起来。

    只是基本的使用,具体的底层原理,并未深究。

    点个赞吧!^_^ !

  • 相关阅读:
    移动端web页面使用position:fixed问题
    登录的一些心得
    响应式网页设计
    xss(跨站脚本攻击),crsf(跨站请求伪造),xssf
    HTML5 离线功能介绍
    webapp开发经验和资料
    学习Java,值得你留意的问题(1)更名为《学习Java,容易被你忽略的小细节(1)》
    Python下搜索文件
    从百度地图API接口批量获取地点的经纬度
    获取代理IP地址(BeautifulSoup)
  • 原文地址:https://www.cnblogs.com/aknife/p/11840347.html
Copyright © 2011-2022 走看看