使用SpringBoot+Mybatis+MySQL完成头像上传

您所在的位置:网站首页 提交完成的图片 使用SpringBoot+Mybatis+MySQL完成头像上传

使用SpringBoot+Mybatis+MySQL完成头像上传

2024-07-02 16:24:28| 来源: 网络整理| 查看: 265

本次主要是使用SpringBoot+Mybatis+MySQL完成用户的头像上传。

头像上传-持久层 规划SQL语句

在数据库中t_user表中的字段avator类型为varchar(50),这么设计有以下原因: 将对象文件保存到操作系统上,然后再把这个文件路径记录下来,因为记录路径是非常便捷和方便的,如果要打开这个文件,可以依据这个路径找到这个文件,所以在数据库中需要保存这个文件的路径即可。大点的公司会将所有的静态资源,比如图片、文件、其他资源文件存放到某台电脑上,再把这台电脑作为一台单独的服务器使用。 故对应的是一个更新用户avator字段的SQL语句:

update t_user set avatar=?.modified_user=?,modified_time? where uid = ? 设计接口和抽象方法

UserMapper接口中来定义个抽象方法用于修改用户的头像。

/** * @Param("SQL映射文件中#{}占位符的变量名") 解决的问题,当SQL语句的占位符和映射的接口方法参数名不一致时, * 需要将某个参数强行注入到某个占位符变量上时,可以使用@Param这个注解来标注映射的关系 * 根据用户uid值来修改用户的头像 * @param uid * @param avatar * @param modifiedUser * @param modifiedTime * @return */ Integer updateAvatarByUid( @Param("uid") Integer uid, @Param("avatar") String avatar, @Param("modifiedUser") String modifiedUser, @Param("modifiedTime") Date modifiedTime); 接口的映射

UserMapper.xml文件中编写映射的SQL语句。

UPDATE t_user SET avatar=#{avatar}, modified_user = #{modifiedUser}, modified_time = #{modifiedTime} WHERE uid = #{uid} 单元测试

在测试类中编写测试的方法

@Test public void updateAvatarByUid() { userMapper.updateAvatarByUid(13,"/upload/avatar.png","管理员", new Date()); }

运行test,运行成功后去数据库进行结果验证。

头像上传-业务层 规划异常 用户数据不存在、找不到对应的用户数据;更新的时候,各种未知的异常。 设计接口和抽象方法

三个参数,uid和modified_user可以从HttpSession中获取。

/** * 修改用户的头像 * @param uid 用户的id * @param avatar 用户头像的路径 * @param username 用户的名称 */ void changeAvatar(Integer uid, String avatar, String username); 实现抽象方法

编写业务层的更新用户头像的方法

@Override public void changeAvatar(Integer uid, String avatar, String username) { // 查询当前的用户数据是否存在 User result = userMapper.findByUid(uid); if (result == null || result.getIsDelete() == 1) { throw new UserNotFoundException("用户数据不存在"); } Integer rows = userMapper.updateAvatarByUid(uid, avatar, username, new Date()); if (rows != 1) { throw new UpdateException("更新用户头像时产生未知的异常"); } } 单元测试

测试业务层方法的执行。

@Test public void changeAvatar() { userService.changeAvatar(13, "/upload/test.png", "admin01"); } 头像上传-控制层 规划异常 文件异常的父类: FileUploadException 泛指文件上传的异常(父类)继承RuntimeException 父类是:FileUploadException FileEmptyException 文件为空的异常 FileSizeException 文件大小超出限制 FileStateException 文件状态的异常 FileTypeException 文件类型异常 FileUploadIoException 文件读写的异常

5个构造方法显式的声明出来,再去继承相关的父类。

处理异常

在基类BaseController类中进行编写和统一处理。

else if (e instanceof FileEmptyException) { result.setState(5003); result.setMessage("文件为空的异常"); } else if (e instanceof FileSizeException) { result.setState(6000); result.setMessage("文件大小限制的异常"); } else if (e instanceof FileTypeException) { result.setState(6001); result.setMessage("文件类型的异常"); } else if (e instanceof FileStateException) { result.setState(6002); result.setMessage("文件状态的异常"); } else if (e instanceof FileUploadIOException) { result.setState(6003); result.setMessage("文件读写的异常"); }

在异常统一处理方法的参数列表上增加新的异常处理作为它的参数。

@ExceptionHandler({ServiceException.class, FileUploadException.class}) 设计请求 /users/change_avatar POST (get请求提交数据2KB) HttpSession session, MultipartFile file JsonResult 实现请求

UserController.java中

/* 设置上传文件的最大值10M */ public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024; /* 限制上传文件的类型 */ public static final List AVATAR_TYPE = new ArrayList(); static { // 初始化 AVATAR_TYPE.add("image/jpeg"); AVATAR_TYPE.add("image/png"); AVATAR_TYPE.add("image/bmp"); AVATAR_TYPE.add("image/gif"); } /** * MultiPartFile 接口式SpringMVC提供的一个接口,这个接口为我们包装了获取文件类型的数据(任何类型的file都可以接收) * SpringBoot它又整合了SpringMVC,只需要在处理请求的方法参数列表上声明一个参数类型为MultiPartFile的参数, * 然后SpringBoot自动将传递给服务的文件数据赋值给这个参数。 * @RequestParam,表示请求中的参数,将请求中的参数注入请求处理方法的某个参数上, * 如果名称不一致可以使用@RequestParam注解进行标记和映射 * @param session * @param file * @return */ @RequestMapping("change_avatar") public JsonResult changeAvatar(HttpSession session, MultipartFile file) { // 判断文件是否为null if (file.isEmpty()) { throw new FileEmptyException("文件为空"); } if (file.getSize() > AVATAR_MAX_SIZE) { throw new FileSizeException("文件超出限制"); } // 判断文件的类型是否是规定的后缀类型 String contentType = file.getContentType(); // 如果集合包含某个元素则返回值true if (!AVATAR_TYPE.contains(contentType)) { throw new FileTypeException("文件类型不支持"); } // 上传的文件.../upload/文件.png String parent = session.getServletContext().getRealPath("upload"); // File对象指向这个路径,File是否存在 File dir = new File(parent); //检测目录是否存在 if (!dir.exists()) { // 创建目录 dir.mkdirs(); } // 上传的文件名称随机生成,获取到这个文件名称,UUID工具生成一个新的字符串作为文件名 // 例如:avatar01.png,保存后缀 String originalFileName = file.getOriginalFilename(); System.out.println("originalFileName = " + originalFileName); int index = originalFileName.lastIndexOf("."); String suffix = originalFileName.substring(index); String filename = UUID.randomUUID().toString().toUpperCase() + suffix; // 是一个空文件 File dest = new File(dir, filename); // 参数file中数据写入到这个空文件中 try { // 将file文件中的数据写入到dest文件中 file.transferTo(dest); } catch (FileStateException e) { throw new FileStateException("文件状态异常"); } catch (IOException e) { throw new FileUploadIOException("文件读写异常"); } Integer uid = getuidFromSession(session); String username = getUsernameFromSession(session); // 返回头像的路径,返回相对路径即可 /upload/test.png String avatar = "/upload/" + filename; userService.changeAvatar(uid, avatar, username); // 返回用户头像的路径给前端页面,用于头像的展示使用 return new JsonResult(OK, avatar); } 头像上传-前端页面

在upload.html页面中编写上传头像的代码。 说明:如果直接使用表单进行文件的上传,需要给表单显式的添加一个属性enctype=”multipart/form-data“声明出来,不会将目标文件的数据结构做修改再上传,不同于字符串。 form表单中增加:

action="/users/change_avatar" method="post" enctype="multipart/form-data"

参考下图: 在这里插入图片描述

解决bug 更改默认的大小限制

SpringMVC默认为1MB文件可以进行上传。手动修改SpringMVC默认上传文件的大小。 方式1:直接可以在配置文件中(application.properties)进行配置。

spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=15MB

方式2:采用java代码的形式来来设置文件的上传大小的限制。 在主类中进行配置,因为主类的加载时间是最早的。 可以定义一个方法,必须用@Bean修饰,在类的前面添加@Configuration注解进行修饰;返回值是MultipartConfigElement类型。

@Configuration //表示配置类 @SpringBootApplication // MapperScan注解指定当前项目中的Mapper接口路径的位置,在项目启动时会自动加载所有的接口 @MapperScan("com.cy.store.mapper") public class StoreApplication { public static void main(String[] args) { SpringApplication.run(StoreApplication.class, args); } @Bean public MultipartConfigElement getMultipartConfigElement() { // 创建一个配置的工厂类对象 MultipartConfigFactory factory = new MultipartConfigFactory(); // 设置需要创建的对象的相关信息 factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES)); factory.setMaxRequestSize(DataSize.of(15, DataUnit.MEGABYTES)); // 通过工厂类来创建MultipartConfigElement对象 return factory.createMultipartConfig(); } } 显示头像

上面的处理方式虽然可以上传成功,实际页面上的图片在返回后是没有更新的,针对这个问题,需要在upload.html文件中做一些改动,通过ajax请求来提交文件,提交完成后返回了json串,并解析出data中的数据,再设置到img头像标签的属性上就可以了。 对upload.html做的修改 删除上面添加的:

action="/users/change_avatar" method="post" enctype="multipart/form-data"

增加id属性:

id="form-change-avator"

将submit改为button,并增加id属性:

之前在前端页面一直使用serialize()解析,但他不能解析文件中的数据,下面做一些说明:

serialize()可以将表单数据自动拼接成key=value的结构提交给服务器,一般提交的是普通控件类型中的数据(text/password/radio/checkbox等)。FormData类:将表单中的数据保持原有的结构进行数据的提交。 new FormData($("#form")[0]); // 文件类型的数据可以使用FormData对象进行存储

ajax默认处理数据时是按照字符串的形式进行处理,以及默认会采用字符串的形式提交数据,所以需要关闭这两个默认的功能。

登录后显示头像

上面的完成后,如果跳转到其他页面再到上传头像页签,之前上传的头像还是不显示的。 可以在上传头像成功后,将服务器返回的头像路径保存到客户端cookie对象中,每次检测到用户打开上传头像页面,可以通过ready()方法来自动检测并读取cookie中的头像设置到src属性上。

① 设置cookie中的值 需要在login.html中设置,导入cookie.js文件

调用cookie方法

$.cookie(key, value, time); // cookie的存活时间单位是:天

② 在upload.html页面先引入cookie.js文件

③ 在upload.html页面通过ready()函数自动读取cookie中的数据

$(document).ready(function () { let avatar = $.cookie("avatar"); console.log(avatar); // 将cookie值获取出来设置到头像的src属性上 $("#img-avatar").attr("src", avatar); }); 显示最新的头像

在更改完头像后,将最新的头像地址,再次保存到cookie,同名保存会覆盖原有cookie中的值。

$.cookie("avatar", json.data, {expires: 7});


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭