当前位置: 首页 > article >正文

【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)

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:ss
    time-zone: GMT+8
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: root
 mybatis-plus:
  type-aliases-package: com.lm.system.common
  mapper-locations: classpath:com.lm.system/mapper/*Mapper.xml
  check-config-location: true
  configuration:
    #日志实现,不配置不会输出SQL日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

SQL

t_file.sql

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50734
 Source Host           : localhost:3306
 Source Schema         : system

 Target Server Type    : MySQL
 Target Server Version : 50734
 File Encoding         : 65001

 Date: 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 {

    @Resource
    private 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) //10MB
            throw 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")
    @ResponseBody
    public 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: system
  servlet:
    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 文件,则页面返回“文件格式有误”,上传失败。
在这里插入图片描述

项目结构图

在这里插入图片描述


http://www.kler.cn/a/388967.html

相关文章:

  • NUXT3学习日记一(在我git中拉取代码、文件讲解)
  • nginx部署H5端程序与PC端进行区分及代理多个项目及H5内页面刷新出现404问题。
  • 探索 HTTP 请求方法:GET、POST、PUT、DELETE 等的用法详解
  • Apache ECharts
  • 15 个改变世界的开源项目:塑造现代技术的先锋力量
  • DHCP与DNS安全管理
  • 关系数据的可视化——Python大数据可视化
  • Android 开启混淆R8编译问题处理
  • nVisual前端目录结构
  • [MySQL#14] 视图 | 用户管理 | 权限设置
  • RTOS IOT 结构
  • 速盾:游戏盾的功能和原理详解
  • 【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)
  • 【SQL】在 SQL Server 中创建数据源是 MySQL 数据表的视图
  • 如何编译安装LNMP环境
  • 论文阅读:人工智能赋能源网荷储协同互动的应用及展望
  • ZISUOJ 2024算法基础公选课练习二
  • WAL日志
  • 逐行加载 HTML 内容并实时显示效果:使用 wxPython 的实现
  • c++中的变量与常量
  • 绿色未来的关键:先进氢气压力容器技术取得重大进展
  • PHP API为什么要使用多种提交方式
  • Linux的基本指令(一)
  • 数仓工具—Hive语法之窗口函数中的order by
  • mybatisgenerator生成mapper时报错
  • Chapter1:python数据结构与算法