7.2 SpringBoot实现上传图片API + url映射本地路径registry.addResourceHandler

news2024/11/27 9:35:49

CSDN成就一亿技术人

文章目录

  • 前言
  • 一、url映射本地路径
  • 二、上传图片API
    • 2.1 接口UploadService
    • 2.2 实现类UploadServiceImpl
    • 2.3 上传图片Controller
  • 三、测试
  • 最后


前言

在图书借阅系统里,有很多图片需要前端展示,这些图片大都是由用户上传,保存在服务端,所以服务端需要提供上传和访问图片
基本要求:前端直接访问网络图片url 就可以打开图片,不用下载,更不用base64转码!

实现方式

  1. Tomcat静态目录,需要单独部署Tomcat,你只需要把图片保存到Tomcat静态目录
  2. SpringBoot添加url映射本地路径,和Tomcat静态目录很像,需要重写WebMvcConfigurer的addResourceHandlers,并registry.addResourceHandler(添加url映射本地路径),同样只需要把图片保存到本地路径即可。
  3. 云对象存储(像oss,cos等),功能丰富,提供加密、裁剪等等很多功能,可以保存各种文件,需要对接API,收费
  4. 图床,专门保存图片,需要对接API

因为我们是基于SpringBoot开发,所以选择方案2,最终的效果:例如访问http://localhost:8080/files/图书借阅系统一期SpringBoot-天罡gg.png,实际是访问E:\projects\files\图书借阅系统一期SpringBoot-天罡gg.png。(window和linux环境原理相同)

在这里插入图片描述

所以,主要实现的是「url映射本地路径」和「上传图片API」,OK,要做的事情说清楚了,接下来实现!


一、url映射本地路径

这是本文的重点!重写WebMvcConfigurer的addResourceHandlers方法。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler(uploadResourceHandler+"/**").addResourceLocations("file:" + uploadResourceLocation);
}

uploadResourceHandler和uploadResourceLocation,由于window和linux路径不成,所以都做成了配置,从配置文件application.properties读取:

// 上传文件的请求路径
@Value("${upload.resource.handler}")
private String uploadResourceHandler;
// 上传文件的映射本地路径
@Value("${upload.resource.location}")
private String uploadResourceLocation;

配置文件application.properties添加配置:

upload.resource.handler=/files
upload.resource.location=E:/projects/files/

另外,拦截器里要排除uploadResourceHandler路径,否则需要登录才能访问。代码融合到了InterceptorConfig类,完整代码如下:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;
    // 上传文件的请求路径
    @Value("${upload.resource.handler}")
    private String uploadResourceHandler;
    // 上传文件的映射本地路径
    @Value("${upload.resource.location}")
    private String uploadResourceLocation;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 身份认证拦截器
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/**")
                // 排除的请求路径
                .excludePathPatterns("/auth/login", "/auth/register", "/auth/test/cors", uploadResourceHandler+"/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(uploadResourceHandler+"/**").addResourceLocations("file:" + uploadResourceLocation);
    }
}

这时,你也可以手动把图片放到目录E:/projects/files/中,然后通过 http://localhost:8080/files/xxx.png 就可以正常访问了~👏👏👏


二、上传图片API

2.1 接口UploadService

在service层增加

public interface UploadService {
    String uploadImage(MultipartFile file);
}

2.2 实现类UploadServiceImpl

在service层的impl包下增加
思路很简单,将图片文件MultipartFile上传到映射的本地路径uploadResourceLocation。
分3步:

  1. 定义文件名:fileName,使用UUID(防止覆盖)+原始文件的扩展名
  2. 将上传的file保存到saveFile, 也就是映射的本地路径uploadResourceLocation
  3. 返回前端可访问的网络地址,这里新增了一个配置upload.host,定义服务器地址
@Service
@Slf4j
public class UploadServiceImpl implements UploadService {
    @Value("${upload.host}")
    private String uploadHost;
    // 上传文件的请求路径
    @Value("${upload.resource.handler}")
    private String uploadResourceHandler;
    // 上传文件的映射本地路径
    @Value("${upload.resource.location}")
    private String uploadResourceLocation;

    @Override
    public String uploadImage(MultipartFile file) {
        // 1.定义文件名:fileName,使用UUID(防止覆盖)+原始文件的扩展名
        String fileName = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        if (originalFilename != null && originalFilename.lastIndexOf(".") >= 0) {
            fileName += file.getOriginalFilename().substring(originalFilename.lastIndexOf("."));
        } else {
            fileName += ".png";
        }
        // 2. 将上传的file保存到saveFile, 也就是映射的本地路径uploadResourceLocation
        File saveFile = new File(uploadResourceLocation, fileName);
        try {
            file.transferTo(saveFile);
        } catch (IOException e) {
            log.error("图片上传失败:{}", e.getMessage(), e);
        }
        // 3. 返回前端可访问的网络地址
        return uploadHost + uploadResourceHandler + "/" + fileName;
    }
}

对于log,后面加上e会打印出详细的堆栈信息。

2.3 上传图片Controller

在controller包下定义UploadController,注入UploadService
文件使用MultipartFile类,Post请求,其它应该都轻车熟路了,不做赘述!

@RestController
@RequestMapping("/upload")
public class UploadController {

    @Autowired
    private UploadService uploadService;

    @PostMapping("/image")
    public TgResult<String> uploadImage(@RequestParam(value = "file") MultipartFile file) {
        //判断文件是否为空
        if (file.isEmpty()) {
            return TgResult.fail("400", "上传图片不能为空");
        }
        String url = uploadService.uploadImage(file);
        return TgResult.ok(url);
    }
}

配置文件application.properties共添加3个配置:

upload.host=http://localhost:8080
upload.resource.handler=/files
upload.resource.location=E:/projects/files/

三、测试

通过Postman调用上传图片API
在这里插入图片描述
将返回的结果用浏览器直接打开如下:
在这里插入图片描述


最后

想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!

具体的优势、规划、技术选型都可以在《开篇》试读!

博主保证会用心持续高质量输出文章哦!

订阅专栏后也可以添加博主的微信,博主会为每一位用户进行针对性指导!

另外,别忘了关注我:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/665121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python拆数程序:如何快速分解数字?

Python拆数程序&#xff1a;如何快速分解数字&#xff1f; 在计算机编程中&#xff0c;数字拆分是一个非常重要的概念。拆分数字可以让我们更好地理解数字格式&#xff0c;进行计算和分析。而Python作为一种功能强大的编程语言&#xff0c;提供了许多高效的工具来帮助我们快速…

【备战秋招】每日一题:华东师范大学保研机试-2022-罗马数字

为了更好的阅读体检&#xff0c;可以查看我的算法学习博客罗马数字 题目内容 罗马数字是古罗马使用的记数系统&#xff0c;现今仍很常见。 罗马数字有七个基本符号: I,V,X,L,C,D,M。 罗马数字IVXLCDM对应的阿拉伯数字1510501005001000 需要注意的是罗马数字与十进位数字的…

chatgpt赋能python:Python拆分语句,让数据处理更有效率

Python 拆分语句&#xff0c;让数据处理更有效率 Python是一种强大的编程语言&#xff0c;不仅支持各种应用开发&#xff0c;而且非常适合数据处理。Python的易用性和灵活性使其成为了数据科学家和工程师首选的编程语言之一。Python的字符串拆分功能能够轻松处理数据的分割和组…

从C语言到C++_20(仿函数+优先级队列priority_queue的模拟实现+反向迭代器)

目录 1. priority_queue的模拟实现 1.1 未完全的priority_queue 1.2 迭代器区间构造和无参构造 1.3 仿函数的介绍和使用 1.4 完整priority_queue代码&#xff1a; 1.5 相关笔试选择题 答案&#xff1a; 2. 反向迭代器 2.1 反向迭代器的普通实现 reverse_iterator.h&a…

性能测试基础知识(一)性能测试策略

性能测试策略 一、什么是性能测试&#xff1f;二、性能测试的目的三、性能测试策略1、基准测试2、并发测试3、负载测试4、压力测试5、其他测试 一、什么是性能测试&#xff1f; 性能测试是在一定的负载1条件下&#xff0c;系统的响应时间等特性是否满足特定的性能需求。需要有…

软考A计划-系统集成项目管理工程师-信息化知识(二)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

【高危】Apache Nifi JMS组件存在JNDI反序列化漏洞

漏洞描述 Apache NiFi 是一个开源的数据流处理和自动化工具&#xff0c; JndiJmsConnectionFactoryProvider 控制器组件用于配置 JMS 连接地址。 Apache NiFi 1.8.0 至 1.21.0 版本中&#xff0c;由于 JndiJmsConnectionFactoryProvider 控制器服务允许已授权的用户配置 URL…

NUCLEO-F411RE RT-Thread 体验 (3) - GCC环境 uart驱动的移植以及console的使用

NUCLEO-F411RE RT-Thread 体验 (3) - GCC环境 uart驱动的移植以及console的使用 1、准备工作 在第一节里&#xff0c;我们用stm32cubemx将pa2 pa3管脚配置成usart2&#xff0c;用于跟st-link虚拟串口的打印用&#xff0c;那么我们先重定向printf函数&#xff0c;看这条通道是…

创建 Python 脚本以在 Linux 中打开新终端并运行命令

文章目录 创建在 Linux 中打开新终端并运行命令的 Python 脚本在 Linux 中创建 Python 脚本来检查 Python 版本使打开的终端保持活动状态并在其中运行命令的 Python 脚本在 Linux 中使用 Python 子模块 subprocess() 将命令传递到新终端总结 Linux 操作系统以其程序员广泛使用的…

PB9如何实现datawindow打印导出PDF,PB导出PDF

PB9如何实现datawindow打印导出PDF&#xff0c;PB导出PDF&#xff1f; 之前的saveas导出pdf&#xff0c;设置非常麻烦。需要 1. 安装gs705w32.exe 2. 安装虚拟打印机 Sybase\Shared\PowerBuilder\drivers\ADIST5.INF 手动添加打印机 这个方法现在对于win64不支持。 今天客…

window11 + python3.7+NVDIA11.7 +pytorch GPU 加速环境配置

window11 python3.7NVDIA11.7 pytorchGPU 加速环境配置 关于pytorch配置GPU环境我在网上看了很多&#xff0c;其实现在基本上没有windows 11 版本环境的配置但是其实没必要担心这个&#xff0c;这没有影响。 对于博主呢&#xff0c;其实不太像配置GPU的&#xff0c;因为其实…

【MYSQL篇】一文弄懂mysql索引原理

文章目录 索引是什么&#xff1f;索引定义索引类型 索引存储模型推演二分查找二叉查找树&#xff08; Binary Search Tree&#xff09;平衡二叉树&#xff08;AVL Tree&#xff09;多路平衡查找树&#xff08;B Tree&#xff09;B树&#xff08;加强版B Tree&#xff09; 小结 …

PyQt中数据库的访问(一)

访问数据库的第一步是确保ODBC数据源配置成功&#xff0c;我接下来会写数据源配置的文章&#xff0c;请继续关注本栏&#xff01; &#xff08;一&#xff09;数据库连接 self.DBQSqlDatabase.addDatabase("QODBC") self.DB.setDatabaseName("Driver{sqlServer…

shell 实现子进程多任务,进程高并发

多进程的作用 提高程序的效率&#xff1a;一些CPU密集型的任务&#xff0c;如数据处理、解压、加密等&#xff0c;使用多进程可以提高程序的执行效率&#xff0c;更快地完成计算任务&#xff1b; 实现更复杂的功能&#xff1a;多进程可以在同一时间向不同的方向处理不同的任务…

SpringBoot创建和运行

1、什么是SpringBoot1.1、优点 2、项目创建2.1、使用Idea创建2.2、使用网页创建 3、项目目录介绍4、项目运行5、包路径错误 1、什么是SpringBoot Spring是为了简化Java程序开发的。Spring Boot是一种用于快速构建独立、生产级别的Java应用程序的开源框架&#xff0c;是为了简化…

MySQL优化--undo log和redo log的区别

首先我们需要知道两个概念 缓冲池&#xff08;buffer pool&#xff09;:主内存中的一个区域&#xff0c;里面可以缓存磁盘上经常操作的真实数据&#xff0c;在执行增删改查操作时&#xff0c;先操作缓冲池中的数据&#xff08;若缓冲池没有数据&#xff0c;则从磁盘加载并缓存…

MySQL数据库基础 13

第十三章 约束 1. 约束(constraint)概述1.1 为什么需要约束1.2 什么是约束1.3 约束的分类 2. 非空约束2.1 作用2.2 关键字2.3 特点2.4 添加非空约束2.5 删除非空约束 3. 唯一性约束3.1 作用3.2 关键字3.3 特点3.4 添加唯一约束3.5 关于复合唯一约束3.5 删除唯一约束 4. PRIMARY…

燃气管网监测系统助力天燃气管道安全运行

随着城市化的进程&#xff0c;燃气管道网络在各个城市中越来越密集&#xff0c;一旦发生燃气泄漏等安全事故&#xff0c;后果将不堪设想。因此&#xff0c;城市燃气管网的建设发展有赖于制定一个安全可靠的监控方案&#xff0c;以保障供气管道与用户安全。物联网技术的发展为城…

北邮国院物联网RFID课程笔记

PDF 获取&#xff1a;微信公众号&#xff1a;灰海宽松&#xff0c;后台回复 “RFID” 获取。 文章目录 RFID1. IntroductionComparison of different automatic identification technologiesThe main features of RFIDConstraints of RFID technologyCore technologies of RFI…

一个cad绘图图型的过程

cad绘图步骤 &#xff1a; 1.设置绘图环境。 选择菜单栏中的“格式”→“图层”命令&#xff0c;新建 3 个图层&#xff1a; 第一图层命名为“粗实线”&#xff0c;线宽为 0.3mm&#xff0c;其余属性默认。 第二图层命名为“细实线”&#xff0c;线宽为 0.15mm&#xff0c;其…