当前位置: 首页 > news >正文

【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)

【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)


文章目录

      • 【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)
        • 1、图片上传流程
        • 2、图片上传接口查看
        • 3、代码开发
          • 3.1、配置Minio Client
          • 3.2、开发上传图片接口
        • 4、异常处理

1、图片上传流程

​ 由于公寓、房间等实体均包含图片信息,所以在新增或修改公寓、房间信息时,需要上传图片,因此我们需要实现一个上传图片的接口。

下图展示了新增房间或公寓时,上传图片的流程。

image-20240614211618302

可以看出图片上传接口接收的是图片文件,返回的Minio对象的URL

2、图片上传接口查看

image-20240614211817521

接口信息:

  • 请求地址: /admin/file/upload
  • 请求类型: POST
  • 请求内容类型: multipart/form-data

请求参数:

参数名称参数说明请求类型是否必须数据类型schema
file文件querytruefile

响应状态:

状态码说明
200OK

响应参数:

参数名称类型参数说明
codeinteger(int32)返回码
messagestring返回信息
datastring数据

响应示例:

{"code": 0,"message": "","data": ""
}

解释:

  • 请求地址:此接口的请求地址是 /admin/file/upload,用于上传文件。
  • 请求类型POST 表示这是一个 POST 请求。
  • 请求内容类型multipart/form-data 表示请求数据需要以多部分表单数据格式发送。
  • 请求参数
    • file:文件,必须提供,用于上传的文件。
  • 响应状态:200 表示请求成功。
  • 响应参数
    • code:返回码,整数类型,表示请求的状态。
    • message:返回信息,字符串类型,描述请求的结果。
    • data:数据,字符串类型,通常包含上传文件的相关信息或 URL。
3、代码开发
3.1、配置Minio Client

引入依赖

common模块pom.xml文件增加如下内容:

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId>
</dependency>

配置Minio相关参数

application.yml中配置Minio的endpointaccessKeysecretKeybucketName等参数

minio:endpoint: http://<hostname>:<port>access-key: <access-key>secret-key: <secret-key>bucket-name: <bucket-name>

**注意:**上述<hostname><port>等信息需根据实际情况进行修改。

common模块中创建com.atguigu.lease.common.minio.MinioProperties,内容如下

@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;private String bucketName;
}

common模块中创建com.atguigu.lease.common.minio.MinioConfiguration,内容如下

@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {@Autowiredprivate MinioProperties properties;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();}
}
3.2、开发上传图片接口

编写Controller层逻辑

FileUploadController中增加如下内容

@Tag(name = "文件管理")
@RequestMapping("/admin/file")
@RestController
public class FileUploadController {@Autowiredprivate FileService service;@Operation(summary = "上传文件")@PostMapping("upload")public Result<String> upload(@RequestParam MultipartFile file) {String url = service.upload(file);return Result.ok(url);}
}

说明:MultipartFile是Spring框架中用于处理文件上传的类,它包含了上传文件的信息(如文件名、文件内容等)。

编写Service层逻辑

FileService中增加如下接口

String upload(MultipartFile file);

FileServiceImpl中增加如下内容

@Autowired
private MinioProperties properties;@Autowired
private MinioClient client;@Override
public String upload(MultipartFile file) {try {boolean bucketExists = client.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());if (!bucketExists) {client.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(properties.getBucketName()).config(createBucketPolicyConfig(properties.getBucketName())).build());}String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();client.putObject(PutObjectArgs.builder().bucket(properties.getBucketName()).object(filename).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build());return String.join("/", properties.getEndpoint(), properties.getBucketName(), filename);} catch (Exception e) {e.printStackTrace();}return null;
}private String createBucketPolicyConfig(String bucketName) {return """{"Statement" : [ {"Action" : "s3:GetObject","Effect" : "Allow","Principal" : "*","Resource" : "arn:aws:s3:::%s/*"} ],"Version" : "2012-10-17"}""".formatted(bucketName);
}

由于公寓、房间的图片为公开信息,所以将其设置为所有人可访问。

4、异常处理

问题说明

上述代码只是对MinioClient方法抛出的各种异常进行了捕获,然后打印了异常信息,目前这种处理逻辑,无论Minio是否发生异常,前端在上传文件时,总是会受到成功的响应信息。可按照以下步骤进行操作,查看具体现象

关闭虚拟机中的Minio服务

systemctl stop minio

启动项目,并上传文件,观察接收的响应信息

问题解决思路

为保证前端能够接收到正常的错误提示信息,应该将Service方法的异常抛出到Controller方法中,然后在Controller方法中对异常进行捕获并处理。具体操作如下

Service层代码

@Override
public String upload(MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException{boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());if (!bucketExists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(properties.getBucketName()).config(createBucketPolicyConfig(properties.getBucketName())).build());}String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) +"/" + UUID.randomUUID() + "-" + file.getOriginalFilename();minioClient.putObject(PutObjectArgs.builder().bucket(properties.getBucketName()).stream(file.getInputStream(), file.getSize(), -1).object(filename).contentType(file.getContentType()).build());return String.join("/",properties.getEndpoint(),properties.getBucketName(),filename);
}

Controller层代码

public Result<String> upload(@RequestParam MultipartFile file) {try {String url = service.upload(file);return Result.ok(url);} catch (Exception e) {e.printStackTrace();return Result.fail();}
}

全局异常处理

按照上述写法,所有的Controller层方法均需要增加try-catch逻辑,使用Spring MVC提供的全局异常处理功能,可以将所有处理异常的逻辑集中起来,进而统一处理所有异常,使代码更容易维护。

具体用法如下,详细信息可参考官方文档:

common模块中创建com.atguigu.lease.common.exception.GlobalExceptionHandler类,内容如下

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseBodypublic Result error(Exception e){e.printStackTrace();return Result.fail();}
}

上述代码中的关键注解的作用如下

@ControllerAdvice用于声明处理全局Controller方法异常的类

@ExceptionHandler用于声明处理异常的方法,value属性用于声明该方法处理的异常类型

@ResponseBody表示将方法的返回值作为HTTP的响应体

注意:

全局异常处理功能由SpringMVC提供,因此需要在common模块pom.xml中引入如下依赖

<!--spring-web-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

修改Controller层代码

由于前文的GlobalExceptionHandler会处理所有Controller方法抛出的异常,因此Controller层就无序关注异常的处理逻辑了,因此Controller层代码可做出如下调整。

public Result<String> upload(@RequestParam MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {String url = service.upload(file);return Result.ok(url);
}

相关文章:

  • 数学术语:“suprema” 和 “supremum”指什么
  • 刺客信条找不到emp.dll怎么解决?emp.dll缺失的解决方法解析
  • Arduino入门1——认识Arduino,点亮一个LED
  • 8个常用的辅助函数!!
  • try-with-resources 工作原理
  • DockerHub无法访问,国内镜像拉取迂回解决方案
  • 万字长文爆肝Spring(一)
  • CSS选择器种类总结
  • Spring Boot中Excel的导入导出的实现之EasyPoi框架使用教程
  • docker安装消息队列mq中的rabbit服务
  • python操作数据库,django操作数据库
  • 【Vue】自学笔记(四)
  • 有没有硅基生命?AGI在哪里?
  • 【面试干货】ArrayList、Vector、LinkedList的存储性能和特性比较
  • 类android设备reset过程
  • 网络传输文件的问题
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Python中eval与exec的使用及区别
  • Redash本地开发环境搭建
  • Redis 懒删除(lazy free)简史
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 扑朔迷离的属性和特性【彻底弄清】
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何进阶一名有竞争力的程序员?
  • 使用docker-compose进行多节点部署
  • 手写双向链表LinkedList的几个常用功能
  • 携程小程序初体验
  • 再次简单明了总结flex布局,一看就懂...
  • 中文输入法与React文本输入框的问题与解决方案
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ​TypeScript都不会用,也敢说会前端?
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • # 职场生活之道:善于团结
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (14)Hive调优——合并小文件
  • (2)STM32单片机上位机
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (一)appium-desktop定位元素原理
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)fock函数详解
  • (自用)网络编程
  • ***利用Ms05002溢出找“肉鸡
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET 8.0 发布到 IIS
  • .net MVC中使用angularJs刷新页面数据列表