[项目经验]——图片上传以及回显

️‍个人网站:code宝藏 ,欢迎访问
如果大家觉得博主写的还不错的话,可以点点关注,及时获取我的最新文章
非常感谢大家的支持与点赞
介绍在Springboot+vue中是如何处理图片上传及回显的

文章目录

    • 后端配置
      • 1、设置 application.yml
      • 2、设置拦截器,对图片静态资源直接放行
      • 3、上传图片控制器
      • 4、FileUtils工具类
    • 前端配置
      • 1、vue使用了element-ui
      • 2、上传方法
      • 3、封装的axios的请求方法:
    • 回显的其他思路

后端配置

1、设置 application.yml

web:
   #存储图片地址
  basePath: K:/myimg
  #资源映射路径前缀
  resourcePrefix: /resource

2、设置拦截器,对图片静态资源直接放行

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    @Value("${web.basePath}")
    String basePath;

    @Value("${web.resourcePrefix}")
    String resourcePrefix;

    //注册Sa-Token的注解拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器,并排除不需要鉴权的路径
        //这里配置自己的拦截器
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns(resourcePrefix+"/**");
    }


    /**
     * 开启跨域
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路由
        registry.addMapping("/**")
            // 设置允许跨域请求的域名
            .allowedOriginPatterns("*")
            // 是否允许证书(cookies)
            .allowCredentials(true)
            // 设置允许的方法
            .allowedMethods("*")
            // 跨域允许时间
            .maxAge(3600);
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //配置拦截器访问静态资源
        registry.addResourceHandler(resourcePrefix+"/**").addResourceLocations("file:"+basePath+"/");
    }
}

3、上传图片控制器

@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${web.basePath}")
    String basePath;
   

    @Value("${web.basePath}")
    String resourcePrefix;
    
    
    @PostMapping("/upload")
    public ResultBean uploadFile(MultipartFile file){
        String oldName = file.getOriginalFilename();
        //进行名字更改,调整成一定的格式
        String newName = FileUtils.getFileName("img",oldName);
        //本地保存的真实地址
        String path = basePath+'/'+newName;
        FileUtils.upload(file, path);
        //返回
        ResultBean res = ResultBean.success();
        //拼接映射资源前缀后,生成回显地址
        String viewPath = resourcePrefix+"/"+newName;
        res.put("imgPath",viewPath);
        return res;
    }
}

4、FileUtils工具类

/**
 * 文件上传工具包
 */
public class FileUtils {

    
    public static boolean upload(MultipartFile file, String realPath) {


        File dest = new File(realPath);

        //判断文件父目录是否存在
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdir();
        }

        try {
            //保存文件
            file.transferTo(dest);
            return true;
        } catch (IllegalStateException e) {
            e.printStackTrace();
            throw new MyException("保存失败");
        } catch (IOException e) {
            e.printStackTrace();
            throw new MyException("保存失败");
        }

    }

    /**
     *创建出这种格式的图片img_2022_02_11095154516.jpg,可以避免与之前的重复了
     *你也可以根据自己情况设计
     * @param name  文件类别
     * @param originFileName 文件初始名
     * @return
     */
    public static String getFileName(String name,String originFileName){
        String fileName = name;
        Calendar cal=Calendar.getInstance();
        int year=cal.get(Calendar.YEAR);
        fileName=fileName + "_" + year;
        int month=cal.get(Calendar.MONTH)+1;
        fileName=fileName+"_";
        if(month<10)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+month;
        //生成文件名的日部分
        int day=cal.get(Calendar.DAY_OF_MONTH);
        fileName=fileName+"_";
        if(day<10)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+day;
        //生成文件名的小时部分
        int hour=cal.get(Calendar.HOUR_OF_DAY);
        if(hour<10)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+hour;
        //生成文件名的分钟部分
        int minute=cal.get(Calendar.MINUTE);
        if(minute<10)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+minute;
        //生成文件名的秒部分
        int second=cal.get(Calendar.SECOND);
        if(second<10)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+second;
        //生成文件名的毫秒部分
        int millisecond=cal.get(Calendar.MILLISECOND);
        if(millisecond<10)
        {
            fileName=fileName+"0";
        }
        if(millisecond<100)
        {
            fileName=fileName+"0";
        }
        fileName=fileName+millisecond;
        //生成文件的扩展名部分,只截取最后单位
        String endName = originFileName.substring(originFileName.lastIndexOf("."));//截取之后的值
        fileName=fileName+ endName;
        return fileName;
    }


}

前端配置

1、vue使用了element-ui

<el-upload
           class="avatar-uploader"
           action="lei"
           :show-file-list="false"
           :http-request="httpRequest"
           >
    <img v-if="imgPath" :src="imgPath" class="avatar" />
    <i v-else class="el-icon-plus avatar-uploader-icon">i>
el-upload>

2、上传方法

//这个是你实际的后端地址
this.basePath=xxx
//实现图片上传功能
httpRequest(item) {
    //验证图片格式大小信息
    const isJPG =
          item.file.type == "image/jpeg" || item.file.type == "image/png";
    if (!isJPG) {
        this.$message.error("上传图片只能是 JPG 或 PNG 格式!");
    }
    if (isJPG) {
        let data = new FormData();
        const that = this;
        data.append("file", item.file);
        apiUpload(data).then((res) => {
            that.imgPath = res.imgPath;
            //拼接实际的后端地址
            that.imgPath =this.basePath + res.imgPath;
        });
    }
}

3、封装的axios的请求方法:

关于具体的封装,可以看我的这一篇文章:vue优雅使用axios

export function apiUpload(data){
    return request({
        url:'/file/upload',
        method:'post',
        data:data
    })
}

回显的其他思路

我在写一块内容的时候还查到了一些其他思路,这里也一并写出来给大家参考

我们前面提供的方法对图片作为静态资源直接放行,不用拦截器拦截,但可能有些人需要对这些图片的访问进行控制,比如进行权限验证呀,那就不能使用这种直接放行的办法了,需要通过controller处理

我们可以通过输出流的方法来获取


    @GetMapping("/view/{imgPath}")
    public void getFeedBackPicture(HttpServletResponse response, @PathVariable("imgPath")String imgPath) throws Exception{
        //basePath,我们存放在本地的实际地址
        String realPath= basePath+'/'+imgPath;
        FileInputStream inputStream = new FileInputStream(realPath);
        int i = inputStream.available();
        //byte数组用于存放图片字节数据
        byte[] buff = new byte[i];
        inputStream.read(buff);
        //记得关闭输入流
        inputStream.close();
        //设置发送到客户端的响应内容类型
        response.setContentType("image/*");
        OutputStream out = response.getOutputStream();
        out.write(buff);
        //关闭响应输出流
        out.close();
    }

前端请求直接通过src来添加具体路径即可

<img src="http://localhost:8080/view/123.png" />

你可能感兴趣的:(项目笔记,java,前端,vue.js)