Java实现用户头像上传

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014745069/article/details/82050372

概述

每次说起文件上传,就不得不提一下前端的实现方式,说来也奇怪,本人最热门的博客居然也是文件上传,3万多的访问量占了总访问量的一多半:《传统form表单提交方式的文件上传与文件存储》,而且,今天搜索“form表单提交文件” 百度第一篇居然就是这篇自己写的文章(下图留个纪念,不知道以后会不会有变化 哈哈)

但是由于这篇文章写得比较早,博客玩的还不6,文章排版很糟糕,因此自己都不愿意看,今天完成了一个类似的功能:用户头像上传,特此重写一篇,巩固记忆。

本功能涉及到的几个知识点:

1、controller层的接收方式

2、IO流相关的文件保存处理(路径问题、写出方式)

3、spring boot 自带tomcat上传文件最大值限制的设置

4、分系统分路径(Windows 或 Linux)

5、文件保存的常规实现思路

实现过程

控制器接收方式

以全栈的角度来分析这个功能,当然少不了前端的实现,但是目前多以前后端分离的方式来开发功能,因此,本篇博客着重讲解后端的spring boot的写法,这是本人认为比较工整的写法,对于前端的实现,可以看本篇博客的补充篇《传统form表单提交方式的文件上传与文件存储》。

Controller的接收方式如下:

    @ApiOperation(value = "设置用户头像", notes = "设置当前用户头像")
    @PutMapping("/profiles")
    public SystemResult setUserProfile(@RequestParam(required = true) MultipartFile profile) {
        return userService.updUserProfile(profile);
    }

请求方式是PUTrequired = true,参数类型为MutipartFile  ,只要是Spring 生态的应用程序,文件的接收都是使用MutipartFile这个类型,它表示通过 mutipart 请求上传了的一个文件。如果多个文件上传,那就用数组,如 MutipartFile[] 。

Service处理

Controller接收到文件后,Service需要完成两个大方向的处理:1、保存文件;2、路径存库

    @Override
    public SystemResult updUserProfile(MultipartFile newProfile) {
        // 根据Windows和Linux配置不同的头像保存路径
        String OSName = System.getProperty("os.name");
        String profilesPath = OSName.toLowerCase().startsWith("win") ? SystemConstant.WINDOWS_PROFILES_PATH
                : SystemConstant.LINUX_PROFILES_PATH;

        if (!newProfile.isEmpty()) {
            // 当前用户
            User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
            String profilePathAndNameDB = userDao.selectUserById(currentUser.getUserId()).getProfilePath();
            // 默认以原来的头像名称为新头像的名称,这样可以直接替换掉文件夹中对应的旧头像
            String newProfileName = profilePathAndNameDB;
            // 若头像名称不存在
            if (profilePathAndNameDB == null || "".equals(profilePathAndNameDB)) {
                newProfileName = profilesPath+ System.currentTimeMillis()+ newProfile.getOriginalFilename();
                // 路径存库
                currentUser.setProfilePath(newProfileName);
                userDao.updateUserProfilePath(currentUser);
            }
            // 磁盘保存
            BufferedOutputStream out = null;
            try {
                File folder = new File(profilesPath);
                if (!folder.exists())
                    folder.mkdirs();
                out = new BufferedOutputStream(new FileOutputStream(newProfileName));
                // 写入新文件
                out.write(newProfile.getBytes());
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
                return new SystemResult(HttpStatus.OK.value(), "设置头像失败", Boolean.FALSE);
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return new SystemResult(HttpStatus.OK.value(), "设置头像成功", Boolean.TRUE);
        } else {
            return new SystemResult(HttpStatus.OK.value(), "设置头像失败", Boolean.FALSE);
        }
    }

注释写的比较细,文件的命名,以及目录的创建,也不需要多说什么了。

关于两个系统中使用的路径,虽然Windows系统中都是使用反斜杠“\” ,但是在Java中反斜杠需要转义,比如:“C:\\用户\\文件夹\\文件.txt”,这样,在存入数据库的时候也会比较难看,后来经过测试发现在Java中使用“/”也是没问题的。上述代码两个路径常量如下:

    /** 头像保存路径 */
    public static final String WINDOWS_PROFILES_PATH = "C:/super_meeting/profiles/";
    public static final String LINUX_PROFILES_PATH = "/root/super_meeting/profiles/";

另外,当前用户的获取是通过shiro中的安全管理器SecurityManager来取得的,我们也可以让页面传入一个用户的ID(如果页面知道的话)这样就适用于任何使用场景了。

修改文件上传限制

如果做到上一步,当你上传的文件过大,可能总是会报如下异常

org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: 
The field profile exceeds its maximum permitted size of 1048576 bytes.

可以看到这是Spring Boot自带的tomcat对上传文件大小的限制,我们需要增加一个配置信息:

@Configuration
public class CommonConfiguration {
    /**
     * 文件上传配置,在application配置文件中设置不起作用!
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // 单个文件最大
        factory.setMaxFileSize("10240KB"); // KB,MB
        // 设置总上传数据总大小
        factory.setMaxRequestSize("102400KB");
        return factory.createMultipartConfig();
    }
}

网上还有直接写在application.properties文件中的方式,但是本人亲测不管用,虽然不是很喜欢这种配置类的书写方式,但也没什么办法,凑合着用吧。

配置文件的写法如下,如果哪位测试可用的话,请文末留言告诉我!!!文末留言告诉我!!!告诉我!!!

spring.http.multipart.maxFileSize = 10Mb

spring.http.multipart.maxRequestSize=100Mb

 测试

查询数据库:

打开swagger选择一张图片,或者你自己写一个form表单,都可以。

 

检查一下 系统盘:

数据库:

完美!!

综上,就是文件上传的全过程,其中省略了DAO层的代码,不过这个不是重点,重点还是我在概述中列出的那几项。如果有任何问题,请文末留言。

猜你喜欢

转载自blog.csdn.net/u014745069/article/details/82050372