SpringMVC之文件的上传下载(教你如何使用有关SpringMVC知识实现文件上传下载的超详细博客)

news2025/1/18 20:56:15

目录

前言

一、文件上传

1. 配置多功能视图解析器(spring-mvc.xml)

2. 添加文件上传页面(upload.jsp)

upload.jsp

3.做硬盘网络路径映射

4. 编写一个处理页面跳转的类

PageController.java

 ClazzController.java

5. 初步模拟上传文件

6.配置目录的配置文件

resource.properties

7. 最终实现文件上传并显示

二、文件下载

方法代码

 jsp页面代码

效果测试

 三、多文件上传

jsp页面显示代码

多文件上传方法

 测试多文件上传

 四、扩展(jrebel插件运用)

安装插件

打开代理服务器

jrebel启动项目

 后续注意事项


前言

        在上一期的博客文章中我们了解学习到了有关SpringMVC框架实现模拟增删改查四大功能实现,今天给大家带来的是SpringMVC实现文件的上传下载功能实现模拟,让我们一起来一探究竟吧。

        在Spring MVC中,文件上传下载是指通过web应用程序上传和下载文件。Spring MVC提供了一些便捷的方式来处理文件上传和下载的流程。在文件上传方面,可以MultipartFile对象来接收和处理客户端上传的文件。而在文件下载方面,可以使用Spring MVC的ResponseEntity和InputStreamResource等类来实现文件下载的功能。

        要进行文件上传,可以通过在控制器方法的参数中声明MultipartFile类型的参数来接收上传的文件,然后通过MultipartFile对象的一些方法(如getOriginalFilename()、getSize()等)可以获取文件的原始名称和大小等信息。接收到文件后,可以将文件保存到指定的位置或进行进一步的处理。

 

一、文件上传

1. 配置多功能视图解析器(spring-mvc.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--1) 扫描com.zking.zf及子子孙孙包下的控制器(扫描范围过大,耗时)-->
    <context:component-scan base-package="com.yx"/>

    <!--2) 此标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    <mvc:annotation-driven />

    <!--3) 创建ViewResolver视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- viewClass需要在pom中引入两个包:standard.jar and jstl.jar -->
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4) 单独处理图片、样式、js等资源 -->
     <mvc:resources location="/static/" mapping="/static/**"/>

<!--    处理文件的上传下载的问题-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 文件最大大小(字节) 1024*1024*50=50M-->
        <property name="maxUploadSize" value="52428800"></property>
        <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
        <property name="resolveLazily" value="true"/>
    </bean>

     <aop:aspectj-autoproxy/>
</beans>

主要是添加下面这段代码

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
    <property name="defaultEncoding" value="UTF-8"></property>
    <!-- 文件最大大小(字节) 1024*1024*50=50M-->
    <property name="maxUploadSize" value="52428800"></property>
    <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
    <property name="resolveLazily" value="true"/>
</bean>

在spring-mvc.xml文件添加之前,在pom.xml也要导入相关的依赖和插件。

2. 添加文件上传页面(upload.jsp)

upload.jsp

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/9
  Time: 16:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>班级logo上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/clz/upload" method="post" enctype="multipart/form-data">
    <label>班级编号:</label><input type="text" name="cid" readonly="readonly" value="${param.cid}"/><br/>
    <label>班级图片:</label><input type="file" name="photo"/><br/>
    <input type="submit" value="上传图片"/>
</form>
</body>
</html>

3.做硬盘网络路径映射

4. 编写一个处理页面跳转的类

PageController.java

package com.yx.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-10 17:03
 * 处理页面跳转的
 */
@Controller
@RequestMapping("/page")
public class PageController {

    @RequestMapping("/page/{page}")
public String toPage(@PathVariable("page") String page){
    return page;
}


    @RequestMapping("/page/{dir}{page}")
    public String toDirPage(@PathVariable("dir") String dir,
                            @PathVariable("page") String page){
        return dir+"/"+page;
    }
}

 ClazzController.java

package com.yx.web;

import com.yx.biz.ClazzBiz;
import com.yx.model.Clazz;
import com.yx.utils.PageBean;
import com.yx.utils.PropertiesUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:25
 */
@Controller
@RequestMapping("/clz")
public class ClazzController {
    @Autowired
    private ClazzBiz clazzBiz;

    //    增
    @RequestMapping("/add")
    public String add(Clazz Clazz){
        int i = clazzBiz.insertSelective(Clazz);
        return "redirect:list";
    }

    //    删
    @RequestMapping("/del/{mid}")
    public String del(@PathVariable("mid") Integer mid){
        int i = clazzBiz.deleteByPrimaryKey(mid);
        return "redirect:list";
    }
    //    改
    @RequestMapping("/edit")
    public String del(Clazz Clazz){
        int i = clazzBiz.updateByPrimaryKeySelective(Clazz);
        return "redirect:list";
    }

//    文件上传
    @RequestMapping("/upload")
    public String upload(Clazz clazz,MultipartFile photo){

        try {
//上传的图片真实存放地址
            String dir= PropertiesUtil.getValue("dir");
//网络服务器访问地址
            String server=PropertiesUtil.getValue("server");

            String filename = photo.getOriginalFilename();
            System.out.println("文件名称:"+filename);
            System.out.println("文件类型:"+photo.getContentType());
            FileUtils.copyInputStreamToFile(photo.getInputStream(),new File(dir+filename));

            clazz.setPic(server+filename);//保存到数据库中
            clazzBiz.updateByPrimaryKeySelective(clazz);//调用方法修改

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "redirect:list";
    }

    //    查
    @RequestMapping("/list")
    public String list(Clazz Clazz, HttpServletRequest request){
//    Clazz接口参数
        PageBean pageBean=new PageBean();
        pageBean.setRequest(request);
        List<Clazz> Clazzs = clazzBiz.ListPager(Clazz, pageBean);
        request.setAttribute("lst",Clazzs);
        request.setAttribute("pageBean",pageBean);
//最终跳转到WEB-IEF/Clazz/list.jsp页面
        return "clz/list";
    }

    //    数据回显
    @RequestMapping("/preSave")
    public String preSave(Clazz Clazz, Model model){
        if (Clazz !=null && Clazz.getCid() !=null && Clazz.getCid() != 0){
            Clazz c = clazzBiz.selectByPrimaryKey(Clazz.getCid());
            model.addAttribute("c",c);
        }
        return "clz/edit";
    }


}

 

5. 初步模拟上传文件

这只是实现了将选中的文件下载到指定的文件夹中,在数据库中未进行修改数据。

6.配置目录的配置文件

resource.properties

dir=D:/photo/upload/
server=/upload/

7. 最终实现文件上传并显示

二、文件下载

方法代码

@RequestMapping(value="/download")
    public ResponseEntity<byte[]> download(Clazz clazz,HttpServletRequest req){

        try {
            //先根据文件id查询对应图片信息
            Clazz clz = this.clazzBiz.selectByPrimaryKey(clazz.getCid());
            String diskPath = PropertiesUtil.getValue("dir");
            String reqPath = PropertiesUtil.getValue("server");
            String realPath = clz.getPic().replace(reqPath,diskPath);
            String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
            //下载关键代码
            File file=new File(realPath);
            HttpHeaders headers = new HttpHeaders();//http头信息
            String downloadFileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");//设置编码
            headers.setContentDispositionFormData("attachment", downloadFileName);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            //MediaType:互联网媒介类型  contentType:具体请求中的媒体类型信息
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

将文件下载的代码添加到指定的Controller类中

 jsp页面代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link
            href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
            rel="stylesheet">
    <script
            src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
    <title>班级列表</title>
    <style type="text/css">
        .page-item input {
            padding: 0;
            width: 40px;
            height: 100%;
            text-align: center;
            margin: 0 6px;
        }


        .page-item input, .page-item b {
            line-height: 38px;
            float: left;
            font-weight: 400;
        }

        .page-item.go-input {
            margin: 0 10px;
        }
    </style>
</head>
<body>
<form class="form-inline"
      action="${pageContext.request.contextPath }/clz/list" method="post">
    <div class="form-group mb-2">
        <input type="text" class="form-control-plaintext" name="cname"
               placeholder="请输入班级名称">
        <!-- 			<input name="rows" value="20" type="hidden"> -->
        <!-- 不想分页 -->
<%--        <input name="pagination" value="false" type="hidden">--%>
    </div>
    <button type="submit" class="btn btn-primary mb-2">查询</button>
    <a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/clz/preSave">新增</a>
</form>

<table class="table table-striped ">
    <thead>
    <tr>
        <th scope="col">班级ID</th>
        <th scope="col">班级名称</th>
        <th scope="col">教员</th>
        <th scope="col">图片</th>
        <th scope="col">操作</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach  var="b" items="${lst }">
        <tr>
            <td>${b.cid }</td>
            <td>${b.cname }</td>
            <td>${b.cteacher }</td>
            <td>
             <img src="${b.pic}" style="height:100px;width: 60px; ">
            </td>
            <td>
                <a href="${pageContext.request.contextPath }/clz/preSave?cid=${b.cid}">修改</a>
                <a href="${pageContext.request.contextPath }/clz/del/${b.cid}">删除</a>
                <a href="${pageContext.request.contextPath }/page/clz/upload?cid=${b.cid}">图片上传</a>
                <a href="${pageContext.request.contextPath }/clz/download?cid=${b.cid}">图片下载</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>

</body>
</html>

效果测试

 三、多文件上传

jsp页面显示代码

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/9
  Time: 16:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>班级logo上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/clz/upload" method="post" enctype="multipart/form-data">
    <label>班级编号:</label><input type="text" name="cid" readonly="readonly" value="${param.cid}"/><br/>
    <label>班级图片:</label><input type="file" name="photo"/><br/>
    <input type="submit" value="上传图片"/>
</form>


<p>多文件上传</p>
<form method="post" action="${pageContext.request.contextPath }/clz/uploads" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <button type="submit">上传</button>
</form>

</body>
</html>

多文件上传方法

@RequestMapping("/uploads")
    public String uploads(HttpServletRequest req, Clazz clazz, MultipartFile[] files){
        try {
            StringBuffer sb = new StringBuffer();
            for (MultipartFile cfile : files) {
                //思路:
                //1) 将上传图片保存到服务器中的指定位置
                String dir = PropertiesUtil.getValue("dir");
                String server = PropertiesUtil.getValue("server");
                String filename = cfile.getOriginalFilename();
                FileUtils.copyInputStreamToFile(cfile.getInputStream(),new File(dir+filename));
                sb.append(filename).append(",");
            }
            System.out.println(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:list";
    }

 测试多文件上传

 这是模拟多文件上传到本地路径,在本地路径的文件夹中会显示该图片。(未进行数据库操作),可根据自己的项目需求进行修改运用,例如在商品的多张图片、药品批量入库等等上。

 四、扩展(jrebel插件运用)

安装插件

 

打开代理服务器

代理服务器放在上传资源中了。注意先启动代理服务器再运用jrebel实现项目运行。

jrebel启动项目

 后续注意事项

 本期博客分享到这,希望老铁能够三连一波。

 

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

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

相关文章

【数据分享】STRM 90米分辨率DEM地形数据(无需转发/全国/分省/分市)

地形数据是我们在各种设计、研究中都经常使用的基础数据&#xff01;之前我们分享过12.5米精度的DEM地形数据、30米精度的DEM地形数据(均可查看之前的文章获悉详情&#xff09;。 本次给大家带来的是90米分辨率的DEM地形数据——STRM 90m高程数据&#xff01;该数据是由美国太…

学成在线-网站搭建

文章目录 代码素材来自b站pink老师 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>学成在线首…

《PWA实战:如何为你的网站增加离线功能和推送通知》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Hbase解决ERROR: KeeperErrorCode = ConnectionLoss for /hbase/master报错

1、在单机模式中&#xff0c;要先修改一个文件&#xff1a;/usr/local/hbase/conf/hbase-site.xml hbase-site.xml内容&#xff1a; <configuration><property><name>hbase.rootdir</name><value>file:///usr/local/hbase/hbase-tmp</value…

dji uav建图导航系列()move_base

文章目录 1、导航框架2、move_base功能包3、amcl功能包4、代价地图的配置4.1、通用配置文件4.2、全局规划配置文件4.3、局部规划配置文件5、局部规划器配置6、launch文件1、导航框架 导航的关键是机器人定位和路径规划两大部分 move_base:实现机器人导航中的最优路径规划 am…

ES8生产实践——pod日志采集(Elastic Agent方案)

pod日志采集方案 方案选型 DaemonSetElastic Agent方案&#xff1a;使用DaemonSet控制器在每个kubernetes集群节点上运行elastic agent服务&#xff0c;业务容器日志目录统一挂载到节点指定目录下。在fleet中配置集成Custom Logs集成策略&#xff0c;指定日志采集目录和inges…

【C语言 C++ 源码】课程设计 学生成绩管理系统

文章目录 演示 对学生的信息、学科成绩进行管理&#xff0c;并进行统计。 对信息进行读写文件操作。自动保存数据到文件。 演示 此课设分为C语言和C两个版本。对于学生数据&#xff0c;会自动保存数据到本地&#xff0c;下次运行自动读取数据。 部分源码&#xff1a; printf…

OceanBase 来参加外滩大会了(内附干货PPT)

9 月 7 日至 9 日&#xff0c;2023 inclusion外滩大会在上海黄浦世博园区举办。8 日&#xff0c;由赛迪顾问与 OceanBase 联合主办的外滩大会“分布式数据库助力数实融合”见解论坛圆满落幕。 数字经济加速发展&#xff0c;数字化转型进入深水区&#xff0c;企业对海量数据的存…

大数据课程L5——网站流量项目的实时业务系统搭建

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握网站流量项目的 Flume—>Kafka 连通; ⚪ 掌握网站流量项目的实时业务系统搭建; 一、Flume—>Kafka 连通 1. 实现步骤 1. 启动三台服务器。 2. 启动 Zookeeper 集群。 执行指…

I2C总线驱动:裸机版、应用层的使用、二级外设驱动三种方法

一、I2C总线背景知识 SOC芯片平台的外设分为&#xff1a; 一级外设&#xff1a;外设控制器集成在SOC芯片内部二级外设&#xff1a;外设控制器由另一块芯片负责&#xff0c;通过一些通讯总线与SOC芯片相连 Inter-Integrated Circuit&#xff1a; 字面意思是用于“集成电路之间…

解决absolute绝对定位带来的div穿透问题

首先来看症状&#xff1a; 按理说蓝色和红色div应该并排同行显示&#xff0c;但是很明显&#xff1a;两个元素重叠了 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv&q…

RNN项目实战——文本输入与预测

在本篇博客文章中&#xff0c;我们将使用pytorch搭建RNN模型来生成文本。 文本输入 神经网络不像人类那样善于处理文本数据。因为绝大多数的NLP任务&#xff0c;文本数据都会先通过嵌入码&#xff08;Embedding code)&#xff0c;独热编码(One-hot encoding)等方式转为数字编码…

python DVWA命令注入POC练习

这里同样是抓包&#xff0c;访问DVWA低难度的命令注入 <?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ];// Determine OS and execute the ping command.if( stristr( php_uname( s ), Windows NT ) ) {// Windows$cmd shell_exec( ping …

RHCSA-VM-Linux基础配置命令

1.代码命令 1.查看本机IP地址&#xff1a; ip addr 或者 ip a [foxbogon ~]$ ip addre [foxbogon ~]$ ip a 1&#xff1a;<Loopback,U,LOWER-UP> 为环回2网卡 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP>为虚拟机自身网卡 2.测试网络联通性&#xff1a; [f…

浅谈OPenGL中的纹理过滤

纹理图像中的纹理单元和屏幕上的像素几乎从来不会形成一对一的对应关系。如果程序员足够细心&#xff0c;确实可以实现这个效果&#xff0c;但这需要在对几何图形进行纹理贴图时进行精心的计划&#xff0c;使出现在屏幕上的纹理单元和像素能够对齐&#xff08;实际上在用OPenGL…

项目协作软件对比分析:各大竞品的优缺点客观评析

随着科技的发展&#xff0c;越来越多的企业和团队开始使用项目协作软件来提高工作效率和协同能力。然而&#xff0c;市场上众多的项目协作软件让许多用户感到困惑&#xff0c;不知道如何选择最适合自己的工具。本文将从多个角度对目前市场上的主要项目协作软件进行客观分析&…

cesium wall (动态立体墙效果)

cesium 动态立体墙效果 以下为源码直接复制可用 实现效果 实现思路 通过修改“material”自定义材质实现动态效果 核心类(WallCorrugationsMaterialProperty )自定义材质 class WallCorrugationsMaterialProperty {constructor(options) {this

51单片机的简易计算器数码管显示仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机的简易计算器数码管显示仿真设计 1.主要功能&#xff1a;2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接 51单片机的简易计算器数码管显示仿真设计( proteus仿真程序原理图报告讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器…

pyqt5设置背景图片

PyQt5设置背景图片 1、打开QTDesigner 创建一个UI&#xff0c;camera.ui。 2、创建一个pictures.qrc文件 在ui文件同级目录下先创建一个pictures.txt&#xff0c;填写内容&#xff1a; <RCC><qresource prefix"media"><file>1.jpg</file>…

基于PyTorch使用LSTM实现新闻文本分类任务

本文参考 PyTorch深度学习项目实战100例 https://weibaohang.blog.csdn.net/article/details/127154284?spm1001.2014.3001.5501 文章目录 本文参考任务介绍做数据的导入 环境介绍导入必要的包介绍torchnet和keras做数据的导入给必要的参数命名加载文本数据数据前处理模型训…