若依-了解头像(文件)上传流程

周知

本文主要记录本人关于自主学习若依框架的部分心得经验,必定有许多不足甚至理解有误的部分,如果对你有帮助我也不胜欢喜;如果发现有错误的地方也希望能够分享指出,一起加油

需求原因

客户内部系统,一般不对外开放,因此不适合将文件(如图片)存放到云上,所以存放在本地服务器中

流程分析

每个(组)截图会配上本人的理解和分析,有不对或不全的地方万望指出

页面

在这里插入图片描述

登录后任意界面点击右上角头像位置选择进入个人中心,选择点击头像位置弹出该窗口,选择本地图片上传;
前端调用接口完成头像更新,在数据库的体现为头像字段内容由空转为图片保存地址
在这里插入图片描述
存取地址默认会将profile替换为若依后端配置的默认文件夹地址
/profile ——> D:/ruoyi/uploadPath

前端

ruoyi-ui\src\views\system\user\profile\userAvatar.vue
在这里插入图片描述
ruoyi-ui\src\api\system\user.js
在这里插入图片描述

若依前端不进行什么处理,负责将页面接收到的文件调用后端接口传到后端,并将图片的读取地址改为后端传回来的保存地址

后端

设计到的类中代码可能过多不便全部截出,附上相对路径可自行查看
src\main\java\com\ruoyi\web\controller\system\SysProfileController.java
在这里插入图片描述

后端获取到前端传来的文件,进行通用的校验和处理
判空、拼接存储地址、更新用户信息(头像地址)、更新token、返回头像地址

src\main\java\com\ruoyi\common\utils\file\FileUploadUtils.java
在这里插入图片描述

若依的文件工具类对传来的文件进行校验和处理
判断文件名是否过长、扩展名(文件类型)是否规范合法、拼接存储地址、调用jar包类和方法进行文件的保存
———————
后面还有两个重载的方法,实际上并不进行什么处理,只是为了应对其他使用场景(如不传)存储文件夹、扩展名等……最终都是调用上述方法进行存储操作

在这里插入图片描述在这里插入图片描述

涉及到的jar包、内置类

jetbrains://idea/navigate/reference?project=ifs_7_0_java&path=E:/Maven/develop/apache-maven-3.5.3/repository/org/springframework/spring-web/5.3.20/spring-web-5.3.20.jar!/org/springframework/web/multipart/MultipartFile.class
在这里插入图片描述

这是是关于以上截图代码中调用到的getOriginalFilename()和transferTo() 方法;
transferTo() 调用到FileCopyUtils工具类进行文件读写以实现头像的本地保存

jetbrains://idea/navigate/reference?project=ifs_7_0_java&path=E:/Maven/develop/apache-maven-3.5.3/repository/org/springframework/spring-core/5.3.20/spring-core-5.3.20.jar!/org/springframework/util/FileCopyUtils.class
在这里插入图片描述

若依文件工具类调用该类的方法进行文件的读写

java\io\OutputStream.java
在这里插入图片描述

该方法为上一张图中的 out.weite(in); 所调用,进行文件写入

jetbrains://idea/navigate/reference?project=ifs_7_0_java&path=E:/Maven/develop/apache-maven-3.5.3/repository/org/springframework/spring-core/5.3.20/spring-core-5.3.20.jar!/org/springframework/util/StreamUtils.class
在这里插入图片描述

同样是对于文件的输入输出流操作;
nutNull() 方法:如果入参1为空,返回message为入参2的异常

附上若依默认文件地址的配置

src\main\resources\application.yml
在这里插入图片描述

新增需求

强化文件类型校验

思路

除了后缀校验之外,另外增加文件真实类型校验

资料

https://blog.csdn.net/qq_42764468/article/details/121522645

实现

src\main\java\com\ruoyi\common\utils\file\FileTypeEnum.java

package com.ruoyi.common.utils.file;

import lombok.Getter;
import java.util.ArrayList;
import java.util.List;

@Getter
public enum FileTypeEnum {
    /**
     * 允许上传的附件类型集合
     */
    // 主要是图片,其他的先注释掉了
    JPEG("jpeg", "FFD8FF"),
    JPG("jpg", "FFD8FF"),
    PNG("png", "89504E47"),
    BMP("bmp", "424D");
//    RTF("rtf", "7B5C727466"),
//    DOC("doc", "D0CF11E0"),
//    DOCX("docx", "504B030414"),
//    PDF("pdf", "255044462D312E");

    /**
     * 允许上传的文件类型的文件后缀
     */
    private final String suffixName;

    /**
     * 允许上传的文件类型的文件头信息
     */
    private final String headCode;

    /**
     * 构造方法
     *
     * @param suffixName 文件后缀名
     * @param headCode   文件头信息
     */
    FileTypeEnum(String suffixName, String headCode) {
        this.suffixName = suffixName;
        this.headCode = headCode;
    }

    /**
     * 获取允许上传的文件类型集合
     *
     * @return List-String
     */
    public static List<String> getFileType() {
        List<String> fileTypeList = new ArrayList<>();
        for (FileTypeEnum fileTypeEnum : FileTypeEnum.values()) {
            fileTypeList.add(fileTypeEnum.getSuffixName());
        }
        return fileTypeList;
    }
}


src\main\java\com\ruoyi\common\utils\file\FileHeaderUtils.java

package com.ruoyi.common.utils.file;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ruoyi.common.exception.file.InvalidExtensionException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
public class FileHeaderUtils {
    /**
     * 文件类型和文件大小校验
     *
     * @param file            上传的附件
     * @param allowedFileType 限制上传附件的类型
     */
    public static String checkFileHeader(MultipartFile file, Set<String> allowedFileType) throws InvalidExtensionException {
        // 去掉了后缀校验和大小校验
        String fileType;
        String fileName = file.getOriginalFilename();
        // 为了防止报错增加的两个变量
        String fileHeader = "其他类型";
        String[] alloweds = new String[allowedFileType.size()];
        // 给alloweds赋值
        int i = 0;
        for (String s : allowedFileType) {
            alloweds[i] = s;
            i++;
        }
        // 文件类型判断 - 校验文件头内容
        try (InputStream inputStream = file.getInputStream()) {
            // 获取到上传文件的文件头信息
            fileHeader = FileHeaderUtils.getFileHeader(inputStream);

            if (StringUtils.isBlank(fileHeader)) {
                log.error("Failed to get file header content.");
                throw new InvalidExtensionException(alloweds, fileHeader, fileName);
//                throw new CommonException(BizCodeEnum.FILE_UPLOAD_TYPE_NOT_ALLOWED);
            }
            // 根据上传文件的文件头获取文件的真实类型
            fileType = getFileType(fileHeader);
            if (StringUtils.isBlank(fileType) || !fileTypeAllowed(fileType, allowedFileType)) {
                log.error("Unsupported file type: [{}]", fileType);
                throw new InvalidExtensionException(alloweds, fileType, fileName);
//                throw new CommonException(BizCodeEnum.FILE_UPLOAD_TYPE_NOT_ALLOWED);
            }
        } catch (IOException | InvalidExtensionException e) {
            log.error("Get file input stream failed.", e);
            throw new InvalidExtensionException(alloweds, fileHeader, fileName);
//            throw new CommonException(BizCodeEnum.ATTACHMENT_UPLOAD_ERROR);
        }
        return fileType;
    }

    /**
     * 文件类型校验
     *
     * @param fileType    待校验的类型
     * @param allowedType 允许上传的文件类型
     * @return true - 满足,false - 不满足
     */
    private static boolean fileTypeAllowed(String fileType, Set<String> allowedType) {
        if (StringUtils.isBlank(fileType) || CollectionUtils.isEmpty(allowedType)) {
            return false;
        }
        return allowedType.contains(fileType);
    }

    /**
     * 据文件的头信息获取文件类型
     *
     * @param fileHeader 文件头信息
     * @return 文件类型
     */
    public static String getFileType(String fileHeader) {
        if (fileHeader == null || fileHeader.length() == 0) {
            return null;
        }
        fileHeader = fileHeader.toUpperCase();
        FileTypeEnum[] fileTypes = FileTypeEnum.values();
        for (FileTypeEnum type : fileTypes) {
            boolean b = fileHeader.startsWith(type.getHeadCode());
            if (b) {
                return type.getSuffixName();
            }
        }
        return null;
    }

    /**
     * 文件头字节数组转为十六进制编码
     *
     * @param content 文件头字节数据
     * @return 十六进制编码
     */
    private static String bytesToHexString(byte[] content) {
        StringBuilder builder = new StringBuilder();
        if (content == null || content.length <= 0) {
            return null;
        }
        String temp;
        for (byte b : content) {
            temp = Integer.toHexString(b & 0xFF).toUpperCase();
            if (temp.length() < 2) {
                builder.append(0);
            }
            builder.append(temp);
        }
        return builder.toString();
    }

    /**
     * 获取文件的文件头信息
     *
     * @param inputStream 输入流
     * @return 文件头信息
     * @throws IOException 异常
     */
    private static String getFileHeader(InputStream inputStream) throws IOException {
        byte[] content = new byte[28];
        inputStream.read(content, 0, content.length);
        return bytesToHexString(content);
    }
}


src\main\java\com\ruoyi\common\utils\file\FileUploadUtils.java

/**
     * 文件大小校验
     *
     * @param file 上传的文件
     * @return
     * @throws FileSizeLimitExceededException 如果超出最大大小
     * @throws InvalidExtensionException
     */
    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, InvalidExtensionException
    {
        // 文件大小
        long size = file.getSize();
        // 不能超过最大值,默认50M
        if (size > DEFAULT_MAX_SIZE)
        {
            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
        }
        // 获取文件名、--扩展名--
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        // 扩展名非空但不被允许——>判断非法类型
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
        {
            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
                        fileName);
            }
            else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
                        fileName);
            }
            else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
                        fileName);
            }
            else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
                        fileName);
            }
            else
            {
                throw new InvalidExtensionException(allowedExtension, extension, fileName);
            }
        }
        // 获取到允许文件头
        List<String> fileType = FileTypeEnum.getFileType();
        Set<String> typeSet = new HashSet<>();
        for (String s : fileType) {
            // 添加到Set中
            typeSet.add(s);
        }
        // 校验文件头
        FileHeaderUtils.checkFileHeader(file, typeSet);
    }
  • 14
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 感谢您的提问。uniapp上传头像的开发流程如下: 1. 在uniapp中使用uni.uploadFile()方法上传头像文件到服务器。 2. 服务器接收到上传文件后,将文件保存到指定的目录中。 3. 服务器返回上传成功的信息给客户端。 4. 客户端根据服务器返回的信息,更新用户的头像信息。 希望以上回答能够帮助您。 ### 回答2: uniapp上传头像的开发流程如下: 1. 创建uniapp项目:首先,需要在开发环境下创建一个uniapp项目。 2. 配置文件路径:在项目的`manifest.json`文件中,配置相应的权限,包括写入外部存储的权限和相机/相册的权限。 3. 创建页面:在项目中创建一个页面,用于实现上传头像的功能。可以通过`uni-upload`组件实现上传功能。 4. 调用相机/相册:在页面中,可以使用`uni.chooseImage`方法调用相机或相册,选择要上传头像图片。 5. 图片预览:选择图片后,可以使用`uni.previewImage`方法进行图片预览,确保选择的图片正确。 6. 图片上传:通过`uni.uploadFile`方法将选择的图片文件上传到服务器,并获取返回的图片地址。 7. 头像显示:将上传成功后的图片地址保存在本地,并在页面中显示头像。可以使用`<image>`组件来展示图片。 需要注意的是,除了以上步骤外,还需要进行一些额外的工作。比如,处理图片的压缩、裁剪等操作,以减少图片的大小和提高用户体验。此外,还需要在服务器端进行相应的接口开发,用于接收和处理上传头像文件。 总结起来,uniapp上传头像的开发流程主要包括项目创建、配置文件路径、页面创建、调用相机/相册、图片预览、图片上传头像显示。通过这些步骤,可以实现头像上传功能并在页面中显示上传头像。 ### 回答3: uniapp 是一种跨平台的开发框架,可以同时开发 iOS、Android 和 Web 等多个平台的应用。下面是 uniapp 开发头像上传流程: 1. 准备工作:首先,需要在 uniapp 的项目中引入头像上传所需的组件和插件,如uni-ui和wx.uploadFile。 2. 样式设计:设计一个头像上传按钮,并设置好按钮的样式。 3. 点击事件:为头像上传按钮添加一个点击事件,在该事件中可以调用 uniapp 提供的 API 获取用户选择的图片。 4. 图片处理:获取到用户选择的图片后,可以进行一些图片处理操作,如裁剪、压缩等。 5. 上传操作:将处理后的图片通过 wx.uploadFile 接口上传至服务器。需要注意的是,需要先获取到服务器的上传地址和 token 等信息用于上传。 6. 上传状态监听:监听上传的状态,可根据返回的结果判断上传是否成功,并进行相应的处理。 7. 保存头像信息:如果上传成功,可以将服务器返回的头像地址保存到本地或发送给后端进行保存。 8. 显示头像:将上传成功的头像地址用于显示用户的头像。 9. 错误处理:对于上传过程中可能出现的错误,需要进行相应的错误处理,如进行提示、日志记录等。 10. 兼容性处理:由于 uniapp 是一个跨平台的框架,需要考虑不同平台上头像上传的兼容性,如处理图片的格式、大小限制等。 以上就是 uniapp 实现头像上传功能的开发流程。通过这个流程,可以实现用户在 uniapp 应用中上传头像的功能,并将上传头像保存至服务器用于显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值