使用SpringMVC模拟文件上传与下载案例

文件上传下载

SpringMVC封装了Tomcat的上传文件功能

在这里插入图片描述

MultipartResolver接口

  • MultipartResolver接口定义了文件上传过程中的相关操作,并对通用性操作进行了封装
  • MultipartResolver接口底层实现类CommonsMultipartResovler
  • CommonsMultipartResovler并未自主实现文件上传下载对应的功能,而是调用了apache的文件上传下载组件

pom.xml

  <dependencies><!-- servlet3.0规范的坐标 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--jsp坐标--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><!--spring的坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><!--springmvc的坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version></dependency><!--文件上传下载--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency></dependencies><build><!--设置插件--><plugins><!--具体的插件配置--><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>80</port><path>/</path></configuration></plugin></plugins></build>

SpringMVC配置

    <mvc:annotation-driven/><context:component-scan base-package="com.itzhuzhu"/><!--配置文件上传处理器--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--设置上传大小--><property name="maxUploadSize" value="1024000000"/></bean>

控制器

@RequestMapping(value = "/fileupload")
public void fileupload(MultipartFile file){// transferTo上传文件用的file.transferTo(new File("file.png"));
}

page.jsp

<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<h1>测试文件上传下载功能!</h1>

fileupload.jsp

<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %><form action="/fileupload" method="post" enctype="multipart/form-data"><%--文件上传表单的name属性值一定要与controller处理器中方法的参数对应,否则无法实现文件上传--%>上传LOGO<input type="file" name="file"/><br/>上传照片:<input type="file" name="file1"/><br/>上传任意文件:<input type="file" name="file2"/><br/><input type="submit" value="上传"/>
</form>

文件上传注意事项

  1. 文件命名问题, 获取上传文件名,并解析文件名与扩展名
  2. 文件名过长问题(可以把用户上传的文件名保存到数据库,用UUID生成一个新的文件名,代替它。)
  3. 文件保存路径
  4. 重名问题
@RequestMapping(value = "/fileupload")
//参数中定义MultipartFile参数,用于接收页面提交的type=file类型的表单,要求表单名称与参数名相同
public String fileupload(MultipartFile file,MultipartFile file1,MultipartFile file2, HttpServletRequest request) throws IOException {System.out.println("file upload is running ..."+file);//        MultipartFile参数中封装了上传的文件的相关信息//        System.out.println(file.getSize());  文件大小//        System.out.println(file.getBytes().length);  文件所有的字节都在这个里面//        System.out.println(file.getContentType());   文件的类型//        System.out.println(file.getName());    file文件名//        System.out.println(file.getOriginalFilename());   上传的文件名//        System.out.println(file.isEmpty());   是否为空//首先判断是否是空文件,也就是存储空间占用为0的文件if(!file.isEmpty()){//如果大小在范围要求内正常处理,否则抛出自定义异常告知用户(未实现)//获取原始上传的文件名,可以作为当前文件的真实名称保存到数据库中备用String fileName = file.getOriginalFilename();//设置保存的路径String realPath = request.getServletContext().getRealPath("/images");//保存文件的方法,指定保存的位置和文件名即可,通常文件名使用随机生成策略产生,避免文件名冲突问题file.transferTo(new File(realPath,file.getOriginalFilename()));}//测试一次性上传多个文件if(!file1.isEmpty()){String fileName = file1.getOriginalFilename();//可以根据需要,对不同种类的文件做不同的存储路径的区分,修改对应的保存位置即可String realPath = request.getServletContext().getRealPath("/images");file1.transferTo(new File(realPath,file1.getOriginalFilename()));}if(!file2.isEmpty()){String fileName = file2.getOriginalFilename();String realPath = request.getServletContext().getRealPath("/images");file2.transferTo(new File(realPath,file2.getOriginalFilename()));}// 重名的问题:不使用用户上传的文件名,把上传的文件名封装成一个变量,再使用UUID重新赋一个名,这样用户的是用户的,服务器的是服务器的String uuid = UUID.randomUUID().toString().replace("-","").toUpperCase();return "page.jsp";
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSR表单校验框架

表单校验的重要性&#xff1a; 表单校验保障了数据有效性、安全性 不适用表单检验数据可以随意输入&#xff0c;导致错误的结果。后端表单校验的重要性&#xff0c;比如输入框采集成绩&#xff0c;如果前端做了检验&#xff0c;但是用户比较牛逼&#xff0c;他在地址栏上直接加…

使用Phantom omni力反馈设备控制机器人

传统的工业机器人普遍采用电机 、齿轮减速器 、关节轴三者直接连接的传动机构&#xff0c;这种机构要求电机与减速器安装在机械臂关节附近&#xff0c;其缺点是对于多关节机械臂&#xff0c;下一级关节的电机与减速器等驱动装置成为上一级关节的额外负载 。这一额外负载带来的负…

Go_配置系统环境MacOS(M1)

在MacOS下和JDK一样&#xff0c;配不配环境其实MacOS都是可以检测的到的&#xff0c;安装好以后直接输入go version是一样可以的&#xff0c;因为都是使用开发工具的&#xff0c;在开发工具里配置的话是样的&#xff0c;如果有习惯的话就配置一下吧 下载安装及配置环境&#xf…

Go_数据类型

数据类型&#xff1a; 计算机存储设备最小信息单位是位&#xff08;bit&#xff09;&#xff0c;最小的存储单元是字节&#xff08;byte&#xff09;&#xff0c;占用字节的不同&#xff0c;所表示能存储的数据长度不同。数据类型用来说明数据的数据的结构&#xff0c;便于后面…

HashMap之扰动函数和低位掩码

我们都知道&#xff0c;hashMap在实现的时候&#xff0c;为了寻找在数组上的位置&#xff0c;主要做了两件事 int hash hash(key); int i indexFor(key, table.length); 这个时候得到i才是数组上的位置。 这两个方法详解如下 JDK8对扰动函数的修改&#xff0c;只进行了一次移…

NE2018届校招内推笔试——数据挖掘

【单选题|2分/题】 1、在只有两类的情况下&#xff0c;二维特征向量通过共享相同的协方差矩阵的正态分布生成&#xff0c;其中协方差矩阵为&#xff1a; 均值向量分别为&#xff1a;&#xff0c;则根据贝叶斯分类&#xff0c;样本分类为&#xff1a;&#xff08;&#xff09; A…

不满足依赖关系

今晚上脑残&#xff0c;替换了实体&#xff0c;把报错的也都替换完成了&#xff0c;但是运行报错&#xff1a; 大概的意思就是说不满足XXXXXX依赖关系&#xff0c;但是找了半天都没有找到&#xff0c;最后是mapper的实体类全路径替换的时候&#xff0c;脑残在后面加上了.java。…

Go_切片(初始化、遍历、截取、修改、append、copy、切片作为函数参数、切片求和、切片求最大值)

切片&#xff1a; 切片的长度是不固定的&#xff0c;可以追加数据&#xff0c;可以理解是一个动态数组&#xff0c;切片的底层是一个结构体切片类型&#xff08;slice&#xff09;本身并不是动态数组或数组指针。它内部通过指针引用底层数组&#xff0c;设定相关属性将操作限定…

阿里巴巴Java开发手册——速读记录

本随笔基于阿里巴巴Java开发手册V1.2&#xff0c;陆陆续续记录一些现阶段能理解的&#xff0c;有启发的内容&#xff0c;并将持续更新 最佳实践——插件使用已经发布为随笔&#xff01;http://www.cnblogs.com/jiangbei/p/7668654.html 一、编程规范 1.命名规范 &#xff08;1&…

Go_指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针

指针&#xff1a; 指针是一个特殊的变量&#xff0c;因为它存储的数据是另一个变量的内存地址&#xff0c;指针本身也是有内存地址的指针的数据类型有int、float、bool、string、数组、结构体指针的作用就是可以通过变量/对象的内存地址去操作变量/对象 注意&#xff1a; 取址运…

Go_面向对象(抽象、封装、继承)

抽象 抽象是一种编程思维方式&#xff0c;是从多个事物中提取共性 例&#xff1a;产品经理和程序员都有工作的方法&#xff0c;但是工作内容不同&#xff0c;可以把工作抽象出来定义为一个方法&#xff0c;具体细节由调用者补充 银行存取款案例&#xff1a; 账号结构体取款方法…

Discrete Logging POJ - 2417(BSGS)

Discrete Logging POJ - 2417 题意&#xff1a;给P&#xff0c;B&#xff0c;N&#xff0c;求最小的L使得 BL≡N (mod P)&#xff0c;其中P是素数。 Baby Step Giant Step 1 #include <cstdio>2 #include <cstring>3 #include <iostream>4 #include <cma…

js 根据固定位置获取经纬度--腾讯地图

1.首先引入jq 和 腾讯地图js <script src"../js/jQuery.js"></script> <script charset"utf-8" src"http://map.qq.com/api/js?v2.exp"></script> 2.html代码部分 <body onload"init()"><button ty…

Golang——string字符串常用函数(Contains、join、Index、Repeat、Replace、Split、Trim、Fields)

更多的还是去官方文档里去看&#xff1a;https://studygolang.com/pkgdoc Contains&#xff1a; 判断字符串中是否包含指定字符串 演示&#xff1a; func main() {str1 : "itzhuzhu"result : strings.Contains(str1, "zhu")fmt.Println(result) }join&a…

[flask 优化] 由flask-bootstrap,flask-moment引起的访问速度慢的原因及解决办法

一周时间快速阅读了400页的《javascript基础教程》&#xff0c;理解了主要概念。解决了一个很久之前的疑问。 我的网站是使用flask框架搭建的&#xff0c;介绍flask web的一本著名的书&#xff08;之前提到过&#xff09;作者搭建个人博客时&#xff0c;向读者推荐了flask-boot…

Go_关键字、编译、转义字符

关键字&#xff1a; 关键字是指被go语言赋予了特殊含义的单词&#xff0c;共25个&#xff0c;关键字不能用于自定义名字&#xff0c;只能在特定语法结构中使用。 breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypec…

并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发

多线程&#xff1a; 多线程就是同时执行多个应用程序&#xff0c;需要硬件的支持同时执行&#xff1a;不是某个时间段同时&#xff0c;cpu切换的比较快&#xff0c;所有用户会感觉是在同时运行 并发与并行&#xff1a; 并行(parallel)&#xff1a;指在同一时刻&#xff0c;有多…

第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)

本章学习如何启动第一个应用程序 1.在前面的分析中我们了解到&#xff0c;在init进程中内核挂接到根文件系统之后&#xff0c;会开始启动第一个应用程序: kernel_init函数代码如下: static int __init kernel_init(void * unused) //进入init进程 …

Golang并发——并发技术Goroutine和channel的使用、定时器、生产者消费者、条件变量、select

Goroutine: goroutine是Go并行设计的核心。goroutine说到底其实就是协程&#xff0c;它比线程更小&#xff0c;十几个goroutine可能体现在底层就是五六个线程&#xff0c;Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB)&#x…

Oozie协作框架

Oozie协作框架 一&#xff1a;概述 1.大数据协作框架 2.Hadoop的任务调度 3.Oozie的三大功能 Oozie Workflow jobs Oozie Coordinator jobs Oozie Bundle 4.Oozie的架构 控制流节点 起始&#xff0c;分支&#xff0c;并发&#xff0c;汇合&#xff0c;结束 动作节点action 5.O…