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

概述

每次说起文件上传,就不得不提一下前端的实现方式,说来也奇怪,本博主最热门的博客居然也是文件上传,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、路径存库

    @Overridepublic 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配置文件中设置不起作用!*/@Beanpublic 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层的代码,不过这个不是重点,重点还是我在概述中列出的那几项。如果有任何问题,请文末留言。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

垃圾回收机制和JVM垃圾回收常见算法

垃圾回收机制和JVM垃圾回收常见算法垃圾回收的好处和特点: 好处: 1. 提高编程效率; 2. 垃圾回收机制保护程序的完整性。特点: 1. 只能回收无用对象的内存空间,对其他物理资源无能为力; 2. 为了更快回收不再…

Java 多线程 —— 死锁与锁的错误用法

引言 死锁状态的大致情况是:Thread_1在获得A对象的锁后,紧接着去请求B对象的锁 ,Thread_2在获得了B对象的锁后,紧接着又去请求A对象的锁,如下图: 一、模拟一个死锁 public class DeadLockDemo {static cl…

Java零基础并发编程入门

Java零基础并发编程入门并发编程主要包括: 线程,同步,future,锁,fork/join, volatile,信号量,cas(原子性,可见性,顺序一致性)&#xf…

Java内置锁——synchronized

一、给对象加把锁 synchronized关键字是Java唯一内置的互斥锁,通过关键字 synchronized 可以保证同一时刻只有一个线程获得某个同步代码块的执行权,但不会导致其他线程执行非同步方法时阻塞。 当获得锁的线程执行完同步代码块后,线程会将锁…

处理对象(toString()方法详解和==与equals方法的区别)

处理对象(toString()方法详解和与equals方法的区别)toString()是一个非常特殊的方法,它是一个自我描述的方法。当程序员直接打印该对象的时候,系统会输出该对象的“自我描述”的信息…

Java并发编程实战——volatile

引言 Java 语言提供了一种弱同步机制——volatile 变量。它的作用是确保将变量的更新操作通知到其他线程。 当把变量声明为volatile后,编译器和运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。 另外&#xff0…

Java中类的加载顺序介绍(ClassLoader)

Java中类的加载顺序介绍(ClassLoader)1、ClassNotFoundExcetpion   我们在开发中,经常可以遇见java.lang.ClassNotFoundExcetpion这个异常,今天我就来总结一下这个问题。对于这个异常,它实质涉及到了java技术体系中的类加载。Java的类加载机…

UP装机部署步骤大纲

Linux装机 插上网线,然后,Ubuntu系统安装(略) 更改root密码 以装机时设置的用户登陆后,sudo修改root用户密码,然后退出,重新登录root。 $ sudo passwd root 下载并安装JDK $ java (根据提…

Java 多线程 —— wait 与 notify

引言 认识一下 Object 类中的两个和多线程有关的方法:wait 和 notify。 wait,当前线程进入 WAITING 状态,释放锁资源。 notify,唤醒等待中的线程,不释放锁资源。 一、使用 wait-notify 实现一个监控程序 实现一个…

重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源

重写equal()时为什么也得重写hashCode()之深度解读以及equal方法与hashCode方法渊源转载自:http://blog.csdn.net/javazejian/article/details/51348320 今天这篇文章我们打算来深度解读一下equal方法以及其关联方法hashCode(),我们准备从以下几点入手分…

Java8————Optional

引言 Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进…

问题反馈信息处理平台开发过程

问题反馈信息处理平台开发过程 “问题反馈信息处理平台”是一个将用户反馈上来的出错信息进行处理和收集的一个平台。 这个项目主要都是在实习的时候由我一个人进行开发,我导师在旁边进行指导完成的。 该项目的技术架构主要是: 前端主要基于Vue框架的…

Java8————Base64

Base64? Base64是一种用64个字符来表示任意二进制数据的方式。 对于二进制文件如图片、exe、音频、视频等,包含很多无法显示和打印的字符,如果希望能够通过记事本这样的文本处理软件处理二进制数据,就需要一个二进制转字符串的转…

大众点评后端项目解析

restful Api是一种设计风格: 启动前端项目:在前端项目根目录 npm install:加载依赖包 npm run mock:提供模拟数据的接口,前端脱离于后台;start /b npm run mock(于后台运行) npm…

Java中类及方法的加载顺序

代码展示 请运行下面代码,查看运行结果,并带着问题,尝试第二次debug程序。 class A {private static int numA;private int numA2;static {System.out.println("A的静态字段 : " numA);System.out.println("A的静态代码块…

新手入门教程-------Spring Boot中集成RabbitMQ

AMQP:是Advanced Message Queuing Protocol的简称,高级消息队列协议,是一个面向消息中间件的开放式标准应用层协议。 定义了以下特性: 消息方向消息队列消息路由(包括:点到点和发布-订阅模式)可…

Java 多线程 —— ReentrantLock 与 Condition

引言 ReentrantLock 是 JUC 下的一个功能强劲的锁工具,支持公平锁、非公平锁,以及多等待队列的 Condition 。 也常常被称为“手动锁”。本篇博客主要分析它的使用方法以及 Condition 实现的一个生产者消费者模式。 一、可替代 synchronized 的手动锁 …

Rabbitmq+Springboot设计秒杀应用

秒杀业务的核心是库存处理,用户购买成功后会进行减库存操作,并记录购买明细。当秒杀开始时,大量用户同时发起请求,这是一个并行操作,多条更新库存数量的SQL语句会同时竞争秒杀商品所处数据库表里的那行数据&#xff0c…

Java8————Stream API

引言 Java8 加入了java.util.stream包,这个包中的相关API将极大的增强容器对象对元素的操作能力。 它专注于对集合对象进行各种便利、高效的聚合操作,或大批量数据处理。 Stream API借助于同样新出现的Lambda表达式,极大的提高了编程效率和…

MySQL数据库知识点总结

数据库: 数据库索引的好处:索引是对数据库表中的一个或多个列的值进行排序的结构,这样检索或者查询某条记录的时候就不在是顺序查找,而是使用特定的查找方式进行查找,如通过二分查找或者是hash值来查找,提高…