SpringMVC之文件上传下载以及jrebel的使用

目录

一、文件上传

1.1 导入依赖

1.2 配置文件上传解析器

1.3 配置服务器存放文件地址

1.3.1 点击编辑Configurations

1.3.2 将项目部署至tomcat服务器上

1.3.3 配置相对路径

1.4 导入PropertiesUtil工具类

1.5 编写resource.properties

1.6 添加sql

1.7 编写PageController类

1.8 编写主页展示界面

1.9 编写文件上传方法

1.10 搭建一个图片上传的操作页面 

二、文件下载

三、多文件上传

四、jrebel的使用

4.1 jrebel插件的安装

4.2 打开代理

4.3 设置jrebel离线

五、收获


一、文件上传

演示代码基于上篇博客:SpringMVC之CRUDicon-default.png?t=N7T8https://blog.csdn.net/weixin_74263417/article/details/132763882?spm=1001.2014.3001.5501

我这里的属性名为jay_music数据表的字段如图  : 

由于我们在上篇已经生成了带图片属性的接口、实体以及配置文件。所以我们就不需要重新逆向生成mapper和model包中的代码了。

1.1 导入依赖

导入依赖:


<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version>
</dependency>

1.2 配置文件上传解析器

在spring-mvc.xml中配置文件上传解析器,代码如下:

<!--    处理文件上传下载问题--><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>

CommonsMultipartResolverMultipartResolver接口的实现类。 

1.3 配置服务器存放文件地址

具体操作如下:

1.3.1 点击编辑Configurations

1.3.2 将项目部署至tomcat服务器上

1.3.3 配置相对路径

注:本地路径名需与resource.properties资源文件中路径保持一致。 

然后保存好即可。

1.4 导入PropertiesUtil工具类

package com.Kissship.utils;import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;public class PropertiesUtil {public static String getValue(String key) throws IOException {Properties p = new Properties();InputStream in = PropertiesUtil.class.getResourceAsStream("/resource.properties");p.load(in);return p.getProperty(key);}}

1.5 编写resource.properties

创建一个名为resource.properties的资源文件,如下:

dir=D:/temp/upload/
server=/upload/

dir作为上传图片的真实地址,而server即是网络访问地址。 

1.6 添加sql

在逆向生成后的musicmapper.xml中加入以下代码:

<select id="listPager" resultType="com.Kissship.model.Music" parameterType="com.Kissship.model.Music" >select*from jay_music<where><if test="mname != null">and mname like concat('%',#{mname},'%')</if></where></select>

紧接着在自动生成的mapper类中加入以下代码:

List<Music> listPager(Music music);

1.7 编写PageController类

然后再创建一个公共路径处理类 PageController类,代码如下:

package com.Kissship.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author Kissship* @site www.Kissship.com* @company xxx公司* @create 2023-09-07-15:01** 用来处理页面跳转*/
@Controller
public class PageController {//<a href="order/preSave">新增</a>   新增界面@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;}}

 1.8 编写主页展示界面

主页代码 list.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><linkhref="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"rel="stylesheet"><scriptsrc="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script><title>JayChou歌单列表</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 }/mic/list" method="post"><div class="form-group mb-2"><input type="text" class="form-control-plaintext" name="mname"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 }/mic/preSave">新增</a>
</form><table class="table table-striped"><thead><tr><th scope="col">歌曲编号</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.mid }</td><td>${b.mname }</td><td>${b.mtype }</td><td>${b.minfo }</td><td><img src="${b.mpic }" style="height: 60px;width: 60px"></td><td><a href="${pageContext.request.contextPath }/mic/preSave?mid=${b.mid}">修改</a><a href="${pageContext.request.contextPath }/mic/del/${b.mid}">删除</a><a href="${pageContext.request.contextPath }/page/mic/upload?mid=${b.mid}">图片上传</a><a href="${pageContext.request.contextPath }/mic/download?mid=${b.mid}">图片下载</a></td></tr></c:forEach></tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>
${pageBean }
</body>
</html>

1.9 编写文件上传方法

在我们的MusicController控制器中增加文件上传的方法进行配置,要增加的代码如下:

//文件上传@RequestMapping("/upload")public String upload(Music music,MultipartFile m){try {
//      3.后端可以直接利用mutipartFile类,接受前端传递到后台的文件//上传的图片真实存放地址String dir = PropertiesUtil.getValue("dir");//网络访问地址String server = PropertiesUtil.getValue("server");String fileName = m.getOriginalFilename();System.out.println("文件名:"+fileName);System.out.println("文件类别:"+m.getContentType());//4.将文件转成流,然后写入服务器(某一个硬盘)FileUtils.copyInputStreamToFile(m.getInputStream(),new File(dir+fileName));music.setMpic(server+fileName);musicBiz.updateByPrimaryKeySelective(music);} catch (IOException e) {e.printStackTrace();}return "redirect:list";}

1.10 搭建一个图片上传的操作页面 

创建一个新的upload.jsp页面作为图片上传操作页面,upload.jsp代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>专辑图片上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/mic/upload" method="post" enctype="multipart/form-data"><label>歌曲编号:</label><input type="text" name="mid" readonly="readonly" value="${param.mid}"/><br/><label>专辑图片:</label><input type="file" name="m"/><br/><input type="submit" value="上传图片"/>
</form>
<form method="post" action="${pageContext.request.contextPath}/mic/uploads" enctype="multipart/form-data"><input type="file" name="files" multiple><button type="submit">上传</button>
</form>
</body>
</html>

然后启动tomcat服务器访问路径进行测试,测试结果如下:

二、文件下载

在Controller层中加入以下代码,如下:

 //文件下载实现@RequestMapping(value="/download")public ResponseEntity<byte[]> download(Music music,HttpServletRequest req){try {//先根据文件id查询对应图片信息Music mic = this.musicBiz.selectByPrimaryKey(music.getMid());String diskPath = PropertiesUtil.getValue("dir");String reqPath = PropertiesUtil.getValue("server");String realPath = mic.getMpic().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;

之后重启tomcat服务器进行测试,结果如下:

三、多文件上传

多文件上传和普通文件上传的区别:

  • 参数类型不同:多文件上传使用MultipartFile[]作为参数类型,而普通文件上传使用MultipartFile作为参数类型。
  • 前端表单处理不同:多文件上传需要使用input[type=“file”]的multiple属性,并选择多个文件进行上传,而普通文件上传只能选择单个文件上传。
  • 后端处理方式不同:多文件上传需要接收文件数组,可以对每个文件进行处理;普通文件上传只能接收单个文件。

在Controller层中加入以下代码,如下:

//多文件上传@RequestMapping("/uploads")public String uploads(HttpServletRequest req, Music music, 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";}

 增加完后重启tomcat服务器进行测试,测试结果如下:

四、jrebel的使用

使用 JRebel 启动项目有以下好处:

  1. 快速部署:JRebel 允许在应用程序运行时热部署代码和资源文件,而无需重新启动整个应用程序。这大大提高了开发效率,省去了传统的重启应用程序的时间。

  2. 即时生效:JRebel 对于大部分代码和资源的修改,都能够实时生效,无须手动重新编译和重新部署。这使得开发人员能够立即看到他们所做的更改的效果,快速迭代开发。

  3. 保持应用状态:JRebel 可以保持应用程序的状态,包括各种已经加载的类、对象、变量等。这意味着在代码修改后,应用程序的状态仍然可以保持不变,不会丢失用户的登录状态、缓存数据等。

  4. 支持多种框架和技术栈:JRebel 不仅适用于 Java SE 和 Java EE 应用程序,还支持许多主流的框架和技术栈,如Spring、Hibernate、Maven、Gradle等。这使得 JRebel 能够应用于各种类型的项目。

  5. 减少开发周期:由于 JRebel 的快速部署和即时生效特性,开发人员可以迅速验证和修改他们的代码,减少了开发周期。这有助于提高团队的开发效率和项目的交付速度。

4.1 jrebel插件的安装

重启后的IDEA是这样的:

但是此时我们还需要打开代理(黑窗口)才可以用jrebel启动项目。如下:

4.2 打开代理

下载代理,进行jrebel的使用:

4.3 设置jrebel离线

打开代理后点击jrebel启动项目,会弹出以下窗口,具体操作如下:

1.在弹出框中Team URL下方第一个输入框输入:

 http://127.0.0.1:8888/0e63ac70-2074-46d3-9de1-46fb2befde0a

2.在第二个输入框输入自己的邮箱。

3.勾选 I agree with the term...

4.最后点击最下方按钮Activete JRebel即可。

设置完jrebel离线之后,在用jrebel插件启动项目之前就可以不打开代理辅助工具了。

五、收获

学习 Spring MVC 文件上传与下载可以给我们带来以下收获:

  1. 扩展技能:掌握 Spring MVC 文件上传与下载技术,可以扩展你的技能范围。这使得你成为一个更全面的开发人员,可以处理包括文件上传与下载在内的更广泛的任务。

  2. 实现功能需求:文件上传与下载是许多 Web 应用程序常见的功能需求。通过学习 Spring MVC 文件上传与下载,你可以满足项目或产品的要求,将其集成到你的应用程序中,让用户能够上传和下载文件。

  3. 提升用户体验:文件上传与下载功能可以提升用户体验,使用户能够方便地上传所需的文件或下载所需的资源。这对于许多应用程序来说是重要的功能特性,可以提高用户的满意度和使用度。

  4. 理解文件操作原理:学习文件上传与下载的实现原理可以让你更深入地理解文件操作的相关概念和技术。你可以了解如何处理文件的输入输出、如何管理文件的存储和访问,以及如何在应用程序中保护文件的安全性。

  5. 强化项目开发能力:掌握文件上传与下载技术可以强化你的项目开发能力。你可以更好地处理文件相关的需求,比如批量文件上传、大文件上传、文件分片上传等,提高开发效率和代码质量。

  6. 解决实际问题:学习文件上传与下载技术可以帮助你解决实际的问题和挑战。你可以应对各种情况,如文件大小限制、文件类型验证、安全性控制等,确保文件操作的可靠性和稳定性。


最后SpringMVC之文件上传下载以及jrebel的使用就到这里,祝大家在敲代码的路上一路通畅!

感谢大家的观看 !

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

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

相关文章

2022年12月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:走迷宫 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。 时间限制:1000 …

pandas笔记:显示中间的省略号

比如我们有这样一个数据&#xff08;Geolife中的数据&#xff09; 如何把中间的省略号完整地输出呢&#xff1f; pd.set_option(display.max_rows, None) data

机器人中的数值优化(十五)——PHR增广拉格朗日乘子法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

Stable Diffusion 免费升级 SDXL 1.0,哪些新特性值得关注?体验如何?5 分钟带你体验!

一、引言 7 月 26 日&#xff0c;Stability AI 发布了 SDXL 1.0&#xff0c;号称目前为止&#xff0c;最厉害的开放式图像生成大模型。 它到底有没有网上说的那么炸裂&#xff1f;真的已经实现了像 midjourney 一样 靠嘴出图 的功能吗&#xff1f;相对于之前的版本&#xff0c;…

专业的视觉特效处理包,FxFactory 8 Pro for Mac助您打造精彩视频

FxFactory 8 Pro for Mac是一款强大的视觉特效处理包&#xff0c;专门为Mac用户设计。它集成了超过200种高质量的视觉效果和过渡效果&#xff0c;可以轻松地应用于各种视频项目中。该软件提供了一个直观的界面&#xff0c;用户可以通过简单拖放操作将特效应用到视频片段上。它支…

oracle将一个用户的表复制到另一个用户

注&#xff1a;scott用户和scott用户下的源表&#xff08;EMP&#xff09;本身就有&#xff0c;无需另行创建。 GRANT SELECT ON SCOTT.emp TO BI_ODSCREATE TABLE ODS_EMP AS SELECT * FROM SCOTT.emphttp://www.bxcqd.com/news/77615.html SQL语句查询要修改密码的用户…

逻辑回归Logistic

回归 概念 假设现在有一些数据点&#xff0c;我们用一条直线对这些点进行拟合&#xff08;这条直线称为最佳拟合直线&#xff09;&#xff0c;这个拟合的过程就叫做回归。进而可以得到对这些点的拟合直线方程。 最后结果用sigmoid函数输出 因此&#xff0c;为了实现 Logisti…

树的引进以及二叉树的基础讲解——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 当我们学习完前面的数据结构&#xff0c;难度也就会上升&#xff0c;但是这个也是非常重要的数据结构。今天我们来学习一种新的数据类型——树。 目录 树的概念以及结构 树的概念 树的相关概念 树的表示 树在实…

Socks5 与 HTTP 代理在网络安全中的应用

目录 Socks5和HTTP代理在网络安全中的应用。 Socks5代理和HTTP代理的优点和缺点。 选择合适的代理IP需要考虑的因素&#xff1a; 总结 在网络安全领域中&#xff0c;Socks5和HTTP代理都扮演着重要的角色。作为两种不同的代理技术&#xff0c;它们在网络安全中的应用各有特点…

02 CSS技巧

02 CSS技巧 clip-path 自定义形状&#xff0c;或者使用自带的属性画圆等circle HTML结构 <body><div class"container"></div> </body>CSS结构 使用*polygon*自定义形状 .container {width: 300px;height: 300px;background-color: re…

建站系列(三)--- 网络协议

目录 相关系列文章前言一、定义二、术语简介三、协议的组成要素四、网络层次划分五、常见网络协议划分六、常用协议介绍&#xff08;一&#xff09;TCP/IP&#xff08;二&#xff09;HTTP协议&#xff08;超文本传输协议&#xff09;&#xff08;三&#xff09;SSH协议 相关系列…

Python小知识 - 如何使用Python进行机器学习

如何使用Python进行机器学习 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 机器学习是人工智能的一个分支&#xff0c;是让计算机自动“学习”。学习的过程是从经验E中获得知识K。经验E可以是一个数据集&#xff0c;比如一个图像数据集。知识K可以是计算机…

【系统设计系列】 负载均衡和反向代理

系统设计系列初衷 System Design Primer&#xff1a; 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版&#xff1a; https://github.com/donnemart…

运算符重载(个人学习笔记黑马学习)

1、加号运算符重载 #include <iostream> using namespace std; #include <string>//加号运算符重载 class Person { public://1、成员函数重载号//Person operator(Person& p) {// Person temp;// temp.m_A this->m_A p.m_A;// temp.m_B this->m_B p…

【算法】快速排序 详解

快速排序 详解 快速排序1. 挖坑法2. 左右指针法 &#xff08;Hoare 法&#xff09;3. 前后指针法4. 快排非递归 代码优化 排序&#xff1a; 排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&…

docker介绍和安装

docker安装 下载Docker依赖组件 yum -y install yum-utils device-mapper-persistent-data lvm2 设置下载Docker的镜像源为阿里云 yum-config-manager --add-repo http://mirrors.aliyun.com/dockerce/linux/centos/docker-ce.repo 安装Docker服务 yum -y install docker-ce 安…

OpenCV项目实战(1)— 如何去截取视频中的帧

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。针对一段视频&#xff0c;如何去截取视频中的帧呢&#xff1f;本节课就给大家介绍两种方式&#xff0c;一种方式是按一定间隔来截取视频帧&#xff0c;另一种方式是截取视频的所有帧。希望大家学习之后能够有所收获&#x…

计算机网络概述

目录 一、计算机网络的作用及互联网概述 1.1计算机网络在信息时代中的作用 1.2基本概念 1.3互联网基础架构发展三个阶段 1.4互联网的标准化工作 二、互联网的组成 2.1互联网组成 2.2互联网的边缘部分 2.3互联网的核心部分 三、计算机网络的类别 3.1计算机网络的定义:…

yapi以及gitlab的容器化部署

yapi部署&#xff1a; https://blog.csdn.net/Chimengmeng/article/details/132074922 gitlab部署 使用docker-compose.yml version: 3 services: web: image: twang2218/gitlab-ce-zh:10.5 restart: always hostname: 192.168.xx.xx environm…

企业架构LNMP学习笔记19

Nginx 第三方模块的使用&#xff1a; Nginx官方没有的功能&#xff0c;开源开发人员定制开发了一些功能&#xff0c;把代码公布出来&#xff0c;可以通过编译加载第三方模块的方式&#xff0c;使用新功能。 NGINX 3rd Party Modules | NGINX shell > tar xvf ngx-fancyinde…