SpringBoot实现文件的上传以及表单数据的同时提交

SpringBoot实现文件以及表单数据的上传

一、前期准备

yml文件

 spring:
   servlet:
    multipart:
      max-file-size: 10MB  #文件上传的最大大小
      file-size-threshold: 10MB

pom文件

    <!--文件的上传下载-->
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

二、前端页面

通过表单传递图片文件的同时上传表单中的数据

 <form method="post" class="form-x" enctype="multipart/form-data" id="registerForm">
                            <!--教练-->
                            <div class="form-group">

                                <div class="label">
                                    <label>球队名称:</label>
                                </div>
                                <div class="field">
                                    <input id="teamName" type="text" class="input w50" value="" name="name"
                                           placeholder="请输入4-6位汉字"/>
                                    <div class=""><span style="margin-left: 30px;color:red" hidden="hidden"
                                                        id="warn"></span></div>
                                </div>

                            </div>
                            <!--球队队标-->
                            <div class="form-group">
                                <div class="label">
                                    <label>球队队标:</label>
                                </div>
                                <div class="field">
                                    <input id="teamLog" type="file" accept="image/png, image/jpeg" name="file"
                                           class="input tips" style="width:25%; float:left;" placeholder="仅支持png或jpg格式"
                                           value=""/>
                                </div>
                            </div>
                            <!--球队简介-->
                            <div class="form-group">
                                <div class="label">
                                    <label>球队简介:</label>
                                </div>
                                <div class="field">
                                    <textarea id="teamIntroduce" class="input" name="intro" style=" height:90px;"
                                              placeholder="请介绍一下自己球队"></textarea>
                                    <div class="tips"></div>
                                </div>
                            </div>
                            <!--球队教练-->
                            <div class="form-group">
                                <div class="label">
                                    <label>球队教练:</label>
                                </div>
                                <div class="field">
                                    <input id="coachName" type="text" class="input w50" name="coach" value=""/>
                                    <div class="tips"></div>
                                </div>
                            </div>
                            <!--队伍人数-->
                            <div class="form-group">
                                <div class="label">
                                    <label>队伍人数:</label>
                                </div>
                                <div class="field">
                                    <input id="memberNumber" type="text" class="input w50" name="memberNumber" value=""
                                           placeholder="球队建队人数不能低于12人"/>
                                    <div class="tips"></div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="label">
                                    <label></label>
                                </div>
                                <div class="field">
                                    <div style="padding:30px;">
                                        <input type="button" class="button button-block bg-main text-big input-big" onclick="clickMe();"
                                               id="apply-button"
                                               value="申请">
                                    </div>
                                </div>
                            </div>
                        </form>

效果图

在这里插入图片描述

使用Ajax提交表单到后台

重点是使用了jQuery使用FormData对象上传文件。

FormData的主要用途有两个:
1、将form表单元素的name与value进行组合,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率。
2、异步上传文件

创建一个空对象:
var formdata=new FormData();  //通过FormData构造函数创建一个空对象
formdata.append("name","laotie");  //可以通过append()方法来追加数据
console.log(formdata.get("name"));  //通过get方法对值进行读取 laotie
formdata.set("name","laoliu");  //通过set方法对值进行设置
console.log(formdata.get("name"));  //laoliu

更多详细 参见 https://developer.mozilla.org/zh-CN/docs/Web/API/FormData

可能出现的问题

sp报Unsupported Media Type Content type '*/*;charset=UTF-8' not supported

ajax默认:Content-Type: application/x-www-form-urlencoded;charset=utf-8
解决:前端ajax提交json数据时  contentType:application/json

JS代码

<script>
        function clickMe() {
            var form = document.getElementById("registerForm"),//先获到表单的JQ对象
                formData = new FormData(form);
            $.ajax({
                url: "/teamRegister",
                type: "post",
                data: formData,
                processData: false, 
                contentType: false, //contentType设置为false。因为是由<form>表单构造的FormData对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false。
                success: function (data) {
                    alert("success!!")
                },
                error: function () {
                    alert("failure!!")
                }
            })
        }
    </script>
    

表单中的提交方式要设置为post 必须添加 enctype="multipart/form-data"
   例如 <form method="post" enctype="multipart/form-data">
       
   input框中的name属性必不可少,要不然传递不到后台,并且应该与实体类的字段保持一致才能自动的封装为JavaBean对象 
       后台需要接收前台的数据,直接与前台的name属性值保持一致即可

 // jq里ajax的processData为true时(默认),不能序列化对象,将直接以data的形式传入,为false时,data序列化
 // 成可传输储存的状态,在这里设成false表示将data数据序列化传输,函数视图可以获取数据,如果在默认为true的情况
 // 下,函数视图获取不到数据

三、后端代码


 @Controller
public class TeamController {
    @Autowired
    private TeamImageServiceImpl teamImageService;
    @Autowired
    private ITeamService teamService;
    @Autowired
    private ITeamIntroduceService teamIntroduceService;

    @RequestMapping(value = "/teamRegister")
    @ResponseBody
    public Map<String, Object> register(Team team, @RequestParam("intro") String intro, @RequestParam("file") MultipartFile file) throws IOException {
        Map<String, Object> map = new HashMap<>();

        String teamName = team.getName();//获取前端传递的队伍名称

        String randomNumber = UUID.randomUUID().toString().replace("-", "");//使用UUID生成唯一标识
//创建一个唯一标识作为评论的主键以及队伍的一个字段,方便用来保存数据将队伍与队伍描述建立起关系

        String oldFilename = file.getOriginalFilename(); //获取文件的原始名

        String extension = FilenameUtils.getExtension(file.getOriginalFilename());//使用FilenameUtils获得文件的后缀(先导依赖Commons-fileUpload)

        String newFileName = teamName + randomNumber + "." + extension; //生成新的文件名(队伍名+随机数+后缀名)

        String fileUploadDir = ResourceUtils.getURL("classpath:").getPath() + "/static/teamImages"; //使用ResourceUtils类路径再获取文件保存的路径


        String namespace = fileUploadDir + newFileName; //队标的全路径(从盘符开始)

        String relativePath = "/static/teamImages" + newFileName; //文件保存的相对路径

        team.setUuidNumber(randomNumber);

        team.setImgPath(relativePath);

        File dateDir = new File(fileUploadDir);

        if (!dateDir.exists()) {
            dateDir.mkdirs();//判断目录是否存在,不存在则直接创建
        }
        file.transferTo(new File(fileUploadDir, newFileName));

        TeamImage teamImage = new TeamImage(oldFilename, newFileName, relativePath, extension, new Date());

        teamService.saveTeam(team);//保存team对象

        teamImage.setTeam(team); //teamImage保存team

        teamImageService.saveTeamImage(teamImage); //保存teamImage

        TeamIntroduce introduce = new TeamIntroduce(randomNumber, team.getId(), intro);
        teamIntroduceService.saveTeamIntroduce(introduce);
        
        return map;
    }

}

效果

在这里插入图片描述

MySQL数据库
在这里插入图片描述

MongoDB
在这里插入图片描述

可能出现的错误

报错Required String parameter ‘xxxx’ is not present
基本上就是前端的数据并没有成功的传递过来,而后端又用@RequestParam(value="name")来接收考虑前端name属性与@RequestParam的参数是否一致

如果前端传入的是json数据那么后端使用
@RequestBody HashMap<String, String> map
进行接收,然后再通过map.get(“name”)获取对应的数据

如果前端传入的是正常表单数据,那么后端使用
@RequestParam("name") String name 或者
@RequestParam(value="name", required = false) String name接收参数

需要注意的是,如果请求类型为delete并且参数类型不是json的话,不能使用通过表单类型提交,参数需要跟到请求url后面,并且后台使用@PathVariable进行获取参数

热门文章

编程学习 ·

【数据结构】-排序-快速排序

~快速排序在平均情况下是效果最好的排序算法~每趟子表的排序都是从两头向中间交替逼近,接下来举一个例子类别排序方法最好时间最坏时间平均时间空间复杂度稳定性序列特征适用于插入排序直接插入排序n(顺序)n2(逆序)n21稳定有序序列+待排序元素+无序序列基本有序/n很小折半插…
编程学习 ·

Eslint配置问题

Eslint配置问题rule规则配置解释Eslint问题解决方案 rule规则配置解释 "no-alert": 0,//禁止使用alert confirm prompt "no-array-constructor": 2,//禁止使用数组构造器 "no-bitwise": 0,//禁止使用按位运算符 "no-caller": 1,//禁止…
编程学习 ·

Linux安全原理简介

Linux安全原理简介介绍在设置Linux计算机的所有阶段,安全性应是首要考虑之一。要在计算机上实施良好的安全策略,需要对Linux的基础知识以及所使用的某些应用程序和协议有充分的了解。Linux的安全性是一个非常重要的主题,并且有许多有关此主题的完整书籍。我不能在本教程中介…
编程学习 ·

服务器使用Nginx部署Springboot项目(jar包)

部署SpringBoot项目到后台Nginx实现多项目反向代理1,将java项目打成jar包2.准备工具3.将jar包传入服务器3.使用Xshell运行jar包4.下载安装nginx5.配置nginx.conf6通过域名访问(成功) 1,将java项目打成jar包 这里我用到的是maven工具这里有两个项目,打包完成后一个为demo.jar,另…
编程学习 ·

python编程练习(小甲鱼)第6-10课

1.python中有两种除法运算,一种是真除,一种是floor除法,/ 是真除,保留浮点数,//是floor除法,去除浮点数保留整数 a = 30/4 #7.5 b = 30//4 #72.请写一个程序打印出 0~100 所有的奇数 for i in range(101):if i % 2==1:print(i)3.爱因斯坦曾出过这样一道有趣的数学题:有一…
编程学习 ·

新能源汽车车载智能终端T-BOX

新能源汽车车载智能终端T-BOX技术解决方案包括:用户端 + 运营后台系统 + 车辆网平台 + 车载终端等总体架构:“端+网”解决方案智能信TBOX终端硬件,TBOX终端与汽车共享、网约及分时租赁商业应用相结合,实现远程开锁,GPS追踪、动力控制管理、闪灯鸣笛寻车等功能。同时,提供…
编程学习 ·

scala写入读取本地文件操作

def write(fileName: String)(datas: Array[String]): Unit = {val writer = new PrintWriter(new File(fileName))println("--------数据写入--------")for (s <- datas) { // println(s)writer.write(s + "\n")}writer.close()}/*** 数据读取** …
编程学习 ·

JS笔记(一)

1.JS基本类型:ECMAScript 中有5种简单数据类型(也称为基本数据类型):Undefined,Null,Boolean,Number和String。一种复杂数据类型:object# typeOf null 的结果为Objectvar n = null var flag = true var s = str var num = 11 var un = undefinedconsole.log(typeof(n)); …
编程学习 ·

程序员:Java数据结构与算法——第十六章·算法设计技术详解

Java数据结构与算法-第十六章算法设计16.1引言在求解一个新问题时,通常的思路是寻找当前问题与已解决问题之间的相似之处,从而轻松找到新问题的求解方法。本章将对各种算法按照不同的方法进行分类,然后在随后的3章中分别介绍3个算法设计思想(即贪婪、分治和动态规划)。16.2分…
编程学习 ·

[指南]-DeepFaceLab 2.0说明和教程(推荐)

DeepFaceLab 2.0指南/教程此教程机翻自:https://mrdeepfakes.com/forums/thread-guide-deepfacelab-2-0-explained-and-tutorials-recommended什么是DeepFaceLab 2.0?DeepFaceLab 2.0是利用机器学习来交换视频中人脸的工具/应用程序。1.0和2.0有什么区别?DFL 2.0有什么新功能…
编程学习 ·

python从入门到放弃8.1选举小程序升级版v.1

马上又要12点了–-–,唉,终于完成选举小程序升级版1了。感觉很happy,但是还是有点脑热,因为,有一些内核总是装不上。。Java还没有正式启航。 一天天的,事是真的多。如果不出意外,我应该会持续升级版本,将这个程序做得越来越完善。不多说了,还是给截图。因为自己去实践才…
编程学习 ·

[STM32] Mac开发STM32之JLink常用方法

Mac开发STM32之JLink常用方法 一、JLink组件 APP JFlash/JFlashLite/JFlashSPI 下载烧录程序 JLinkConfig 升级固件 JLinkGDBServer 连接Target,设置为GDB server JLinkRemoteServer 设置主机+Jlink为远程server JLi…
编程学习 ·

zabbix 安装

文章目录zabbix 4.0 安装安装php7.2(也可以跳过这个依赖)安装mcrypt扩展安装仓库配置包安装 zabbix-server-mysql、zabbix-web-mysql 及zabbix-agent安装 zabbix-server-mysqlzabbix数据库创建创建数据库 zabbix添加zabbix账号导入数据:zabbix_server 配置修改启动zabbix_serve…
编程学习 ·

2020抖音小店入驻流程

原文链接:https://blog.ccswust.org/15574.html一、访问入驻后台使用电脑浏览器打开网址https://sso.douyin.com/login/?service=https://fxg.jinritemai.com/index.html#/home,选择【抖音号登陆】,【重要,一定要登录自己的抖音号,才能把店铺和抖音号绑定在一起】※建议请…
编程学习 ·

XGBoost学习总结

XGBoost学习总结极端梯度提升算法XGBoost是2014年提出的基于CART回归树的一种boosting集成算法,是对梯度提升决策树(GBDT)算法的一种改进.它的目标是建立t棵回归树使得树群对样本的预测值尽可能接近样本的真实值,并且具有一定的泛化能力.本文是对XGBoost学习的总结与思考,通过总…
编程学习 ·

图解面试题:如何交换数据?

原创 猴子 猴子数据分析 2月6日【题目】小明是一所学校的老师,她有一张 ‘学生表’,平时用来存放座位号和学生的信息。其中,座位号是连续递增的。总的座位数是偶数。现在,小明想改变相邻俩学生的座位。你能不能帮她写一个sql查来输出想要的结果呢?示例查询结果如下:【解题…
编程学习 ·

彻底理解Cookie Session token

Cookie cookie 是一个非常具体的东西,指的是浏览器中能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能 Cookie的内容是保存一小段文本信息,这些文本信息组成一份通行证。它是客户端对于无状态协议的一种解决方案。 Cookie的原理 (1)客户端第一次请求时,发送数据…
编程学习 ·

CAN协议要点及车辆CAN协议破解

一、CAN协议要点1. 电压2. 波形3. CAN报文概述CAN一共规定了5中类型的帧,帧也称为报文。CAN总线的数据帧有标准格式(Standard Format)和扩展格式(Extended Format)的区分。4. CAN报文编码格式Intel格式编码当一个信号的数据长度不超过1 Byte,并且信号在一个字节内实现时,…
编程学习 ·

类型转化的原理

类型转化的原理类型转化(为了便于硬件的实现)1. 强制类型转换2. 隐式类型转换(1)运算转换(2)赋值类型转换(3)输出类型转换:(4)函数调用转换:3.讨论 类型转化(为了便于硬件的实现) 1. 强制类型转换 一般形式:(类型名)(表达式) 例:double x = 2.1, y-= 1.2;(…