【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 文件,则页面返回“文件格式有误”,上传失败。
在这里插入图片描述

项目结构图

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库_SQLite3

下载 1、更新软件源&#xff1a; sudo apt-get update 2、下载SQLite3&#xff1a; sudo apt-get install sqlite3 3、验证&#xff1a; sqlite3启动数据库&#xff0c;出现以下界面代表运行正常。输入 .exit 可以退出数据库 4、安装sqlite3的库 sudo apt-get install l…

全星魅-物联网定位终端-北斗定位便携终端-北斗有源终端

在当今快速发展的物流运输行业中&#xff0c;精准定位与实时监控已成为确保货物安全与高效运输的关键因素。为了满足这一需求&#xff0c;QMCZ10作为一款集4G&#xff08;LTE Cat1&#xff09;通讯技术与智能定位功能于一体的终端产品&#xff0c;应运而生。它不仅具备普通定位…

微服务系列六:分布式事务与seata

目录 实验环境说明 前言 一、分布式事务问题与策略 1.1 分布式事务介绍 1.2 分布式事务解决策略分析 二、分布式事务解决方案 Seata 2.1 认识Seata 2.2 Seata的工作原理 2.3 部署Seata微服务 2.3.1 准备数据库表 2.3.2 准备配置文件 2.3.3 docker部署 2.4 微服务集…

【数字图像处理+MATLAB】对图片进行伽马校正(Gamma Correction):使用 imadjust 函数进行伽马变换

引言 伽马校正&#xff08;Gamma Correction&#xff09;是一种用于图像处理的技术&#xff0c;主要用于调整图像的亮度或对比度。其基本原理是对图像的每一个像素应用一个非线性变换&#xff0c;以更好地适应人眼的视觉感知。在数字图像处理中&#xff0c;伽马校正通常用于调…

数据挖掘实战-基于SARIMA时间序列模型预测Netflix股票未来趋势

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决

1、问题背景 代码上库公司git后,将项目上出的程序烧录到设备中,wifi能够正常链接&#xff0c;但是通过wifi链接 ssh登录设备失败。把调试串口引出,查看linux启动log,发现如下打印信息&#xff1a; WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 075…

第三十五篇:HTTP报文格式,HTTP系列二

HTTP 是超⽂本传输协议&#xff0c;也就是HyperText Transfer Protocol。 前面我们讲到第三章中网络协议的定义&#xff0c;网络协议的定义&#xff1a;网络协议是通信计算机双方必须共同遵从的一组约定。就像两个人要进行交流&#xff0c;如果不制定一套约定&#xff0c;一方…

嵌入式学习(8)-EventOS 事件驱动管理

一、概述 EventOS&#xff0c;是一个面向单片机、事件驱动的嵌入式开发平台。它主要有两大技术特色&#xff1a;一是事件驱动&#xff0c;二是超轻量。 EventOS的主要特性列举如下&#xff1a; &#xff08;1&#xff09;事件总线为核心组件&#xff0c;灵活易用&#xff0c…

json字符串与python字典的区别与联系

json字符串与python中自带的字典类型外表长的很像&#xff0c;很容易区分不清楚&#xff0c;它们之间有着本质的区别&#xff0c;可以通过内置的json模块来互相转换。 文章目录 1、Python字典2、JSON数据格式3、JSON与python字典的区别4、JSON与python字典相互转换4.1 json字符…

Ubuntu 20.04 安装 QGC v4.3 开发环境

Ubuntu 20.04 安装 QGC开发环境 1. 准备安装 Qt 5.15.2安装依赖获取源码 2. 编译参考 前言 QGC ( QGroundControl) 是一个开源地面站&#xff0c;基于QT开发的&#xff0c;有跨平台的功能。可以在Windows&#xff0c;Android&#xff0c;MacOS或Linux上运行。它可以将PX4固件加…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十二:在屏幕上显示多路视频播放,可以有不同的分辨率,格式和帧率。

上图是在安防领域的要求&#xff0c;一般都是一个屏幕上有显示多个摄像头捕捉到的画面&#xff0c;这一节&#xff0c;我们是从文件中读取多个文件&#xff0c;显示在屏幕上。 一 改动UI文件 这里我们要添加两个label&#xff0c;为了区分我们设置一下背景色&#xff08;这个是…

【数据集】【YOLO】【目标检测】道路垃圾识别数据集 8805 张,垃圾堆放识别数据集,YOLO垃圾识别算法实战训练教程!

数据集介绍 【数据集】道路垃圾识别、垃圾堆放识别数据集 8805 张&#xff0c;目标检测&#xff0c;包含YOLO/VOC格式标注。 数据集中包含2种分类&#xff1a;{0: garbage, 1: garbage_bag}&#xff0c;分别是普通垃圾和垃圾袋。 数据集来自国内外图片网站和视频截图&#x…

《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(2)

《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;2&#xff09; 《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;2&#xff09;回声客户端的完美实现回声客户端的问题回声客户端问题的解决方…

类加载过程详解

类的生命周期 类从被加载到虚拟机内存中开始到卸载出内存为止&#xff0c;它的整个生命周期可以简单概括为 7 个阶段&#xff1a;加载&#xff08;Loading&#xff09;、验证&#xff08;Verification&#xff09;、准备&#xff08;Preparation&#xff09;、解析&#xff08…

03-构建数据中台的三要素:方法论、组织和技术

03-构建数据中台的三要素&#xff1a;方法论、组织和技术 知道要转型&#xff0c;要建设数据中台&#xff0c;却不知咋做&#xff0c;咋办&#xff1f; 现在有很多讲“如何建设数据中台”文章&#xff0c;观点各不相同&#xff1a; 数据中台是数据建设方法论&#xff0c;按照数…

华为Mate70前瞻,鸿蒙NEXT正式版蓄势待发,国产系统迎来关键一战

Mate 70系列要来了 上个月&#xff0c;vivo、小米、OPPO、荣耀等众多智能手机制造商纷纷发布了他们的年度旗舰产品&#xff0c;手机行业内竞争异常激烈。 同时&#xff0c;华为首席执行官余承东在其个人微博上透露&#xff0c;Mate 70系列将标志着华为Mate系列手机达到前所未有…

源代码防泄密管理分享

随着信息技术的快速发展&#xff0c;软件已成为现代企业不可或缺的核心资产之一。然而&#xff0c;源代码作为软件的心脏&#xff0c;其安全性直接关系到企业的核心竞争力。为了有效防止源代码泄露&#xff0c;构建一套全面且高效的源代码安全管理体系显得尤为重要。以下是六个…

从神经元到神经网络:深度学习的进化之旅

神经元、神经网络 神经元 Neuron )&#xff0c;又名感知机( Perceptron )&#xff0c;在模型结构上与 逻辑回归 一致&#xff0c;这里以一个二维输入量的例子对其进行进一步 的解释&#xff1a; 假设模型的输 入向 量是一 维特征向 (x1,x2). 则单神 经元的模型结构 如下…

[C语言]strstr函数的使用和模拟实现

1.strstr函数的使用 char * strstr ( const char *str1, const char * str2); 返回一个指向str1中str2第一次出现的指针&#xff0c;如果str2中没有str1则返回 NULL。。 实例&#xff1a; #include <stdio.h> #include <string.h> int main() {char str[] "…

【论文速读】| RePD:通过基于检索的提示分解过程防御越狱攻击

基本信息 原文标题&#xff1a;RePD: Defending Jailbreak Attack through a Retrieval-based Prompt Decomposition Process 原文作者&#xff1a;Peiran Wang, Xiaogeng Liu, Chaowei Xiao 作者单位&#xff1a;University of Wisconsin–Madison 关键词&#xff1a;越狱…