Java实现用户头像上传(修改默认文件大小限制)

本文重写用户头像上传功能相关博客。着重讲解后端Spring Boot写法,涉及controller层接收方式、IO流文件保存处理、Spring Boot自带tomcat上传文件最大值限制设置、分系统分路径及文件保存思路等知识点,最后进行测试,展示了文件上传全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

每次说起文件上传,就不得不提一下前端的实现方式,说来也奇怪,本博主最热门的博客居然也是文件上传,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层的代码,不过这个不是重点,重点还是我在概述中列出的那几项。如果有任何问题,请文末留言。

 

<think>嗯,用户想在基于Java和Vue的企业管理软件中,实现右上角显示登录用户头像的功能。首先,我需要理清楚整个流程,从前端到后端再到数据库的每个环节。 首先,用户上传头像。Vue前端需要一个上传组件,可能用element-ui的el-upload,或者第三方库如vue-cropper来处理图片裁剪。上传的时候,需要将图片发送到后端。这时候,应该用axios之类的库发起POST请求,把图片数据FormData传过去。上传成功后,后端需要保存图片到服务器或者云存储,并返回图片的URL地址。然后,前端需要把这个URL保存到用户的信息中,可能需要调用更新用户信息的接口,比如updateUserAvatar。 接下来,用户登录后,如何获取头像呢?用户登录成功后,后端应该返回用户信息,包括头像的URL。前端需要把这个URL存到Vuex或者localStorage里,方便全局使用。然后在右上角的组件里,比如导航栏组件,用<img :src="avatarUrl">动态绑定头像地址。如果用户没有头像,可能需要显示默认的logo。 后端方面,Java这边需要处理文件上传的接口。用Spring Boot的话,可以用MultipartFile接收文件,保存到指定目录或者云存储,生成唯一的文件名,避免冲突。然后,更新用户的avatar字段,保存图片路径到数据库。用户信息接口也要能返回这个路径,这样前端才能获取到。 数据库方面,用户表需要添加一个avatar字段,存储图片的路径,比如相对路径或者完整的URL。这样查询用户信息时就能直接拿到头像地址。 权限验证也不能忘记,上传和获取头像的接口都需要用户认证,可以通过JWT或者Spring Security来管理。确保只有登录的用户才能修改自己的头像。 另外,图片的存储位置要考虑。如果存在本地,可能需要配置nginx来代理静态资源,让前端能通过URL访问。或者使用云存储服务,比如阿里云OSS,这样更方便扩展,但需要处理上传到云端的逻辑。 可能遇到的问题包括跨域,这时候需要后端配置CORS。图片大小限制,后端要设置合适的文件大小限制。还有安全性,防止上传非图片文件,需要对文件类型做校验。 优化方面,可以考虑头像缓存,比如加时间戳防止缓存,或者使用CDN加速。另外,图片压缩和裁剪在前端处理,减少传输量。还有,使用云存储提高可用性和扩展性。 总之,整个流程需要前后端协作,处理好文件上传、存储、URL管理和前端显示。每个步骤都要考虑安全性和性能,确保用户体验流畅。</think>### 分步解决方案:Java+Vue实现用户头像右上角显示 --- #### **一、技术实现流程** 1. **头像上传与存储** - **前端组件**:使用Vue的`<el-upload>`或`vue-cropper`组件实现裁剪上传[^3] ```vue <template> <el-upload :action="uploadUrl" :show-file-list="false" :on-success="handleAvatarSuccess"> <img v-if="avatarUrl" :src="avatarUrl" class="avatar" /> </el-upload> </template> ``` - **后端接口**:Java通过`MultipartFile`接收文件并保存到本地/云存储 ```java @PostMapping("/uploadAvatar") public String uploadAvatar(@RequestParam("file") MultipartFile file) { String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); Path path = Paths.get("uploads/" + fileName); Files.write(path, file.getBytes()); return "/static/" + fileName; //返回访问路径 } ``` - **数据库更新**:将文件路径保存到用户表的`avatar`字段[^1] 2. **登录后获取用户信息** - **登录接口**:返回用户信息时包含头像URL ```json { "id": 1, "username": "admin", "avatar": "/static/avatar_123.jpg" } ``` - **前端存储**:通过Vuex或`localStorage`缓存用户信息 ```javascript // 登录成功后 localStorage.setItem('user', JSON.stringify(response.data)); ``` 3. **右上角头像显示** - **导航栏组件**:从缓存中读取头像URL并渲染 ```vue <template> <div class="header"> <img :src="user.avatar || defaultLogo" class="user-avatar" /> </div> </template> <script> export default { computed: { user() { return JSON.parse(localStorage.getItem('user')) || {}; } } } </script> ``` --- #### **二、核心代码实现** 1. **Java后端文件处理** ```java // Spring Boot配置文件上传路径 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") .addResourceLocations("file:uploads/"); //映射本地路径为静态资源 } } ``` 2. **Vue动态绑定头像** ```javascript // 从接口获取最新用户信息 async getCurrentUser() { const res = await axios.get('/api/user/info'); this.avatarUrl = res.data.avatar; } ``` --- #### **三、关键配置说明** | 环节 | 配置项 | 作用说明 | |------------|-----------------------|-----------------------------------| | 前端 | axios baseURL | 统一接口地址 | | Nginx | 静态资源代理配置 | 通过`location /static`映射本地文件夹 | | Spring Boot| `spring.servlet.multipart.max-file-size` | 控制上传文件大小上限 | --- #### **四、常见问题处理** 1. **跨域问题** 在Spring Boot中配置CORS: ```java @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST"); } }; } ``` 2. **头像更新延迟** 在URL后添加时间戳强制刷新: ```vue <img :src="avatarUrl + '?t=' + Date.now()" /> ``` --- #### **五、扩展优化建议** 1. **云存储方案**:使用阿里云OSS替代本地存储,提升访问速度[^4] 2. **图片压缩**:前端上传前通过canvas压缩图片 3. **安全校验**:后端添加文件类型白名单验证 ```java if(!file.getContentType().startsWith("image/")) { throw new IllegalArgumentException("仅支持图片文件"); } ``` ---
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值