服务端本地图片存储 / 读取的方案

需求

        将前端传递过来的图片存储到项目的一个指定目录中,并且将图片在项目中的相对路径存储到数据库中存储,前端获取相对路径后可以直接访问到该图片上

技术实现:

        在SpringBoot项目中,我们可以在resource目录下创建一个 "static" 目录,在此目录下,我们可以放置图片 / HTML等静态页面,并且可以直接在浏览器上访问到,示例如下:

然后我们访问 IP:项目端口 / 项目前缀 / 从static目录开始的资源路径 就可以访问到该静态资源啦

难点1.资源热部署失败:

        现在的需求要求我们能实现一个类似于热部署的状态,就是说将图片上传保存好后,不需要重启项目重新编译加载该图片就可以直接进行访问,然而我在网上找了一些文章进行idea的项目热部署后还是无法达到预期的效果

解决:

        由于公司的项目需要部署到服务器上和前端进行交互(部署到了宝塔上),当前端上传了一张图片后,在宝塔界面的jar包目录中就会生成一个子目录

 我点开发现它的目录结构和项目的目录结构一致,并且上传的图片都一致

         在测试后发现,当我在外部浏览器直接访问该目录下的照片数据后是可以直接获取到的,那么问题就很明显了

难点2.怎么获取到jar包以外的数据?

        由于我将项目打包为jar包后,按照前面的方式,我访问到的实际上还是jar包内部的已经编译好的固定代码,但我新引进的图片实际上是存储在脱离jar包位置以外的一个子目录中,所以肯定是无法达到预期的。

解决:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:pipayshop-api/src/main/resources/static/images/");
    }
}

        这段代码是一个Spring Boot的配置类,用于配置Web应用程序中的资源处理器。

        在这段代码中,WebConfig类实现了WebMvcConfigurer接口,并重写了addResourceHandlers方法。该方法用于配置静态资源的处理器。

        在这个例子中,addResourceHandlers方法注册了一个资源处理器,用于处理以"/images/"开头的URL请求。这些请求将被映射到指定的资源位置。

        具体来说,addResourceHandler("/images/**")指定了URL模式,即以"/images/"开头的所有请求。而addResourceLocations("file:pipayshop-api/src/main/resources/static/images/")指定了资源的存储位置,即在项目的pipayshop-api/src/main/resources/static/images/目录下。

        这样配置之后,当应用程序收到以"/images/"开头的URL请求时,它将会去寻找并返回对应的静态资源文件,以供客户端访问。

        这段代码的作用是将项目中指定目录下的静态图片资源映射到指定的URL路径,使得这些图片可以通过URL访问。


最终效果:

        我在前端上传了一张图片,后端处理后将该图片存储在static下的一个目录中,将该相对路径存储到数据库,查询数据的时候就直接返回该相对路径,前端直接访问 IP:项目端口 / 项目前缀 / 从static目录开始的资源路径 就可以访问到该静态资源啦


工具类分享:

        针对该套图片上传业务实现,封装好了一个工具类给xdm简化操作啦,直接CV操作起来!

   public static String uploadFile(MultipartFile multipartFile,String path) {
        if (multipartFile.isEmpty()) {
            throw new BusinessException("文件不能为空") ;
        }

        String fileName = multipartFile.getOriginalFilename();

        if ("".equals(fileName)) {
            return "文件名不能为空";
        }
        
        String postStr = fileName.substring(fileName.lastIndexOf("."));
        String preStr = StringUtil.generateShortId();
        fileName = preStr +  postStr;
        File readPath = new File(UPLOAD_PRE+PRE+path);
        if (!readPath.isDirectory()) {
            readPath.mkdirs();
        }
        //将文件复制到指定路径
        File destFile = new File(readPath.getAbsolutePath()+SEPARATOR + fileName);


        try {
            FileCopyUtils.copy(multipartFile.getBytes(), destFile);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return SEPARATOR+PRE+path+SEPARATOR+fileName;
    }

        通过该方法,我们只需要传进来文件对象以及他在resources / static / images目录下的具体一个子包目录,我们就可以实现将该文件对象存储到该指定的子包目录中

使用讲解: 

Controller:

@PostMapping("itemTopImags")
    @ApiOperation("网店头像图片上传")
    public ResponseVO<String> itemTopImagsUp(MultipartFile multipartFile){
        try {
            String itemTopImags = FileUploadUtil.uploadFile(multipartFile, FileUploadUtil.ROOM_TOP_IMG);
            return ResponseVO.getSuccessResponseVo(itemTopImags);
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("网店头像图片上传失败,请联系后台人员");
        }
    }
public static final String ROOM_TOP_IMG="room_top_img";

该接口接收到一张图片后,最后图片就会被存储到一下位置 

猜你喜欢

转载自blog.csdn.net/weixin_73077810/article/details/132214201