摘要:
本文主要介绍了文件上传功能的实现,重点讲解了MinIO对象存储服务的使用。MinIO是一个开源的高性能对象存储系统,兼容Amazon S3 API,支持分布式存储和高可用性。文件上传接口通过Spring MVC的MultipartFile类简化操作,使用MinIO客户端进行文件存储,确保文件名唯一性,并返回文件的访问URL。此外,文章还简要提及了房间信息管理、预约看房管理以及后台管理系统的登录功能,包括验证码生成与验证、用户名和密码的校验等。整体内容涵盖了文件存储、数据管理和用户认证等多个模块的实现细节。
一,文件管理(图片)
1,minio的简单介绍
(1)简介:
MinIO 是一个开源的、高性能的对象存储系统,兼容 Amazon S3 API,广泛应用于企业级存储解决方案,支持分布式存储,数据可以分散存储在多个节点上,确保高可用性和数据冗余。
(2)存储单元:
- 桶(Bucket):MinIO 中的最基本组织单位,类似于文件夹,用于隔离和管理对象。
- 对象(Object):MinIO 存储的基本单元,可以是文件、图片、视频等,支持大文件存储(最高 5TB)
2,上传文件接口(MultipartFile是SpringMVC提供简化文件上传操作的工具类)
(1)注入minioclient调用相关方法,minioclient的方法调用格式固定,且很容易见文知意,如:bucketExists(),makeBucket().....等等。
(2)需要保证桶中文件名字唯一,所以这里采用日期+随机UUID+文件名称来作为文件在桶中的名称,使用SimpleDateFormat类指定日期格式。
(3)minio采用流的方式上传文件,同时必须指定文件在浏览器中的类型,如果Content-Type是application/octet-stream等类型浏览器会直接下载,默认流上传就是application类型,所以我们必须指定文件原类型,即:images和jpg类型(会直接展示)
(4)拼接并返回图片在桶中的url(访问地址+桶名+文件名),使得用户可以访问到图片信息
public String upload(MultipartFile file) throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
//判断桶是否存在
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().
bucket(minioProperties.getBucketName()).
build());
if (!exists) {
//创建一个新的桶
minioClient.makeBucket(MakeBucketArgs.builder().
bucket(minioProperties.getBucketName()).
build());
//配置桶的权限
minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().
bucket(minioProperties.getBucketName()).
config(createBucketConfig(minioProperties.getBucketName())).
build());
}
//构造上传的文件的唯一名字
String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
//上传文件bucket桶名 stream文件流 object桶中文件的名字
minioClient.putObject(PutObjectArgs.builder().
bucket(minioProperties.getBucketName()).
stream(file.getInputStream(), file.getSize(), -1).
object(filename).
//设置类型,如果Content-Type是application/octet-stream等浏览器会直接下载
//如果为images和jpg等会直接展示-->一般要指定好
contentType(file.getContentType()).
build());
//返回url-->访问地址+桶名+文件名
return String.join("/", minioProperties.getEndpoint(), minioProperties.getBucketName(), filename);
}
二,房间信息管理
该模块的所有接口与公寓信息管理中的接口非常相似,完成的思路几乎没有区别,自行完成即可,唯一需要注意就是仔细观察需要返回的类和接收的类,避免混淆。
项目数据库设计大致是公寓某某关系表+某表+房间某某关系表的方式,所以一般查询都是从关系表中查询某表id,然后再到对应表中查询需求信息
三,预约看房管理
1,分页查询预约信息
(1)条件查询中引入了模糊匹配-->sql中的like关键字
<if test="queryVo.name != null and queryVo.name != ''">
and va.name like concat('%',#{queryVo.name},'%')
</if>
<if test="queryVo.phone != null and queryVo.phone != ''">
and va.phone like concat('%',#{queryVo.phone},'%')
</if>
(2)引入<association>标签处理一个类中包含另一个复杂类的映射问题,也可以开启自动映射,只需要手动映射与主表中同名的字段即可
<association property="apartmentInfo" javaType="com.atguigu.lease.model.entity.ApartmentInfo" autoMapping="true">
<id property="id" column="ai_id"/>
<result property="name" column="ai_name"/>
<result property="phone" column="ai_phone"/>
</association>
四,后台管理系统登录管理
后台管理采用密码+图形验证码的方式进行登录,所以引入生成验证码的依赖easy-captcha和redis的起步依赖
1,获取图形验证码接口
将图片通过toBase64()转换为字符串类型传输到前端,验证码统一转换为小写,方便用户忽略大小写,这里的key表示存储到redis中的验证码的key,而不是真正的验证码
返回结果是CaptchaVo类,类中存储的信息如下
public class CaptchaVo {
@Schema(description="验证码图片信息")
private String image;
@Schema(description="验证码key")
private String key;
}
public CaptchaVo getCaptcha() {
//得到一个验证码图片
SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);
//得到验证码文本,统一转换成小写
String code = specCaptcha.text().toLowerCase();
//生成一个key用于存储(拼接信息前缀一般有特定要求)
String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID();
//将验证码文本存储到redis中,设置过期时间60秒
template.opsForValue().set(key, code, RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);
//返回CaptchaVo,image是specCaptcha通过Base64方法转换成的
return new CaptchaVo(specCaptcha.toBase64(), key);
}
2,登录接口实现
(1)验证码判断三件套,输入验证码是否为空?redis取出的code是否为空?code与用户填写的验证码是否相等?统一使用自定义异常处理这些情况。
//判断验证码是否为空
if (loginVo.getCaptchaCode()==null){
throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);
}
//redis中取出code,如果没有说明已经过期
String code = template.opsForValue().get(loginVo.getCaptchaKey());
if (code==null){
throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);
}
//判断验证码是否正确(将用户输入的验证码转换为小写)
if(!code.equals(loginVo.getCaptchaCode().toLowerCase())){
throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);
}
(2)进行用户名和密码验证三件套判断,查询用户信息是否为空?用户状态是否有效?用户密码是否与填写的密码一致?同样统一使用自定义异常处理这些情况,最后返回token。
//数据库中查询systemUser对象,数据库中没有这个数据会返回空->账号不存在
SystemUser systemUser = systemUserMapper.querySystemUser(loginVo.getUsername());
if(systemUser==null){
throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
}
//账号存在,判断状态是否被禁用
if(systemUser.getStatus()== BaseStatus.DISABLE){
throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
}
//账号存在且未被禁用,判断密码是否正确
if (!systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
}
833

被折叠的 条评论
为什么被折叠?



