Git仓库
https://gitee.com/Lin_DH/system
介绍
使用 Thymeleaf 写的页面,将(txt、jpg、png)格式文件上传到 MySQL 数据库中。
依赖
pom.xml
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency>
数据库配置
application.yml
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootmybatis-plus:type-aliases-package: com.lm.system.commonmapper-locations: classpath:com.lm.system/mapper/*Mapper.xmlcheck-config-location: trueconfiguration:#日志实现,不配置不会输出SQL日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
SQL
t_file.sql
/*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50734Source Host : localhost:3306Source Schema : systemTarget Server Type : MySQLTarget Server Version : 50734File Encoding : 65001Date: 18/10/2024 15:14:51
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_file
-- ----------------------------
DROP TABLE IF EXISTS `t_file`;
CREATE TABLE `t_file` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`format` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`data` longblob NOT NULL,`size` double NOT NULL,`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;
实现代码
第一步:编写上传页面
uploadToBD.html
<!DOCTYPE html>
<html lang="en">
<head lang="en"><meta charset="UTF-8" /><title>文件上传到数据库页面</title>
</head>
<body>
<h1>文件上传到数据库页面</h1>
<form method="post" action="/uploadToDB" enctype="multipart/form-data">请选择要上传的txt/jpeg/png格式文件:<input type="file" name="file"><br><hr><input type="submit" value="提交">
</form>
</body>
</html>
第二步:编写文件实体类
SysFile.java
package com.lm.system.common;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** @author DUHAOLIN* @date 2024/10/17*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SysFile {@TableId(value = "id", type = IdType.INPUT)private Integer id;private String name;private String format;private byte[] data;private long size;private Date createTime;}
第三步:编写dao层接口
SysFileMapper.java
package com.lm.system.mapper;import com.baomidou.dynamic.datasource.annotation.DS;
import com.lm.system.common.SysFile;/*** @author DUHAOLIN* @date 2024/10/17*/
//@DS("system")
public interface SysFileMapper {int insertFile(SysFile file);}
第四步:编写dao层SQL
SysFileMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lm.system.mapper.SysFileMapper"><resultMap id="beans" type="com.lm.system.common.SysFile"><id property="id" column="id" jdbcType="INTEGER" /><result property="name" column="name" jdbcType="VARCHAR" /><result property="format" column="format" jdbcType="VARCHAR" /><result property="data" column="data" jdbcType="BLOB" /><result property="size" column="size" jdbcType="DOUBLE" /> <result property="createTime" column="create_time" jdbcType="TIMESTAMP" /></resultMap><insert id="insertFile" parameterType="com.lm.system.common.SysFile">INSERT INTO t_file (NAME, FORMAT, DATA, SIZE)VALUES (#{name}, #{format}, #{data}, #{size})</insert></mapper>
第五步:添加 controller
FileController.java
import com.lm.system.exception.FileException;
import com.lm.system.mapper.SysFileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;/*** @author DUHAOLIN* @date 2024/10/15*/
@Controller
public class FileController {@Resourceprivate SysFileMapper fileMapper;private final static String FILE_FORMAT_TXT = "txt";private final static String FILE_FORMAT_JPEG = "jpg";private final static String FILE_FORMAT_PNG = "png";@Value("${file.upload.path}")private String path;private void checkFile(MultipartFile file, String[] fileFormats) {//校验文件大小checkSize(file.getSize());//校验文件名checkFilename(file.getOriginalFilename());//校验文件格式checkFileFormat(file.getOriginalFilename(), fileFormats);}private void checkSize(long size) {if (size > 10485760L) //10MBthrow new FileException("文件大于10MB");}private void checkFilename(String filename) {if (!StringUtils.hasText(filename))throw new FileException("文件名有误");}private void checkFileFormat(String filename, String[] fileFormats) {int i = filename.lastIndexOf(".");String suffix = filename.substring(i + 1); //文件后缀long c = Arrays.stream(fileFormats).filter(s -> s.equals(suffix)).count(); //判断是否存在该文件后缀if (c < 1) throw new FileException("文件格式有误,该文件类型为:" + suffix);}@GetMapping("uploadToDBPage")public String uploadToDBPage() {return "uploadToDB";}@PostMapping("uploadToDB")@ResponseBodypublic String uploadToDB(@RequestParam("file") MultipartFile file) throws IOException {//校验文件try {String[] fileFormats = { FILE_FORMAT_TXT, FILE_FORMAT_JPEG, FILE_FORMAT_PNG };checkFile(file, fileFormats);} catch (FileException e) {e.printStackTrace();return e.getMessage();}//构建存储对象SysFile sysFile = SysFile.builder().name(getFilename(file.getOriginalFilename())).format(getFileFormat(file.getOriginalFilename())).data(file.getBytes()).size(file.getSize()).build();int i = fileMapper.insertFile(sysFile);return i > 0 ? "添加成功" : "添加失败";}private String getFileFormat(String filename) {int i = filename.lastIndexOf(".");return filename.substring(i + 1); //文件后缀}/*** 获取不带后缀的文件名*/private String getFilename(String originalFilename) {int i = originalFilename.lastIndexOf(".");return originalFilename.substring(0, i);}}
第六步:配置默认 tomcat 最大吞吐量
application.yml
server:port: 8888 tomcat:max-swallow-size: 100MB #tomcat的最大吞吐量,默认为2MB,-1则为不限制spring:application:name: systemservlet:multipart:max-file-size: 10MB #默认为1MB max-request-size: 10MB #默认为10MB
上传大于配置文件设定的文件后,页面无响应。
添加上 tomcat 最大吞吐量配置,则能够正常返回。
存在全局异常捕获的可以把文件最大文件限制异常捕获的也加上。
GlobalExceptionHandler.java
@Value("${spring.servlet.multipart.max-file-size}")private String maxFileSize;@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler({MaxUploadSizeExceededException.class})public String handleMaxUploadSizeException(Exception e, HttpServletRequest request) {log.error("400-上传文件超过最大限制{},{},{}", maxFileSize, e.getMessage(), request.getServletPath());e.printStackTrace();return ResultBody.build(HttpStatus.BAD_REQUEST).setMsg("上传文件超过最大限制" + maxFileSize).getReturn();}
效果图
txt
上传 txt 格式文件,添加成功。
jpg
上传 jpg 格式文件,添加成功。
png
上传 png 格式文件,添加成功。
csv
上传允许格式之外的格式文件,如 csv 文件,则页面返回“文件格式有误”,上传失败。