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

目录

一、文件上传

[1.1 导入依赖](#1.1 导入依赖)

[1.2 配置文件上传解析器](#1.2 配置文件上传解析器)

[1.3 配置服务器存放文件地址](#1.3 配置服务器存放文件地址)

[1.3.1 点击编辑Configurations](#1.3.1 点击编辑Configurations)

[1.3.2 将项目部署至tomcat服务器上](#1.3.2 将项目部署至tomcat服务器上)

[1.3.3 配置相对路径](#1.3.3 配置相对路径)

[1.4 导入PropertiesUtil工具类](#1.4 导入PropertiesUtil工具类)

[1.5 编写resource.properties](#1.5 编写resource.properties)

[1.6 添加sql](#1.6 添加sql)

[1.7 编写PageController类](#1.7 编写PageController类)

[1.8 编写主页展示界面](#1.8 编写主页展示界面)

[1.9 编写文件上传方法](#1.9 编写文件上传方法)

[1.10 搭建一个图片上传的操作页面](#1.10 搭建一个图片上传的操作页面)

二、文件下载

三、多文件上传

四、jrebel的使用

[4.1 jrebel插件的安装](#4.1 jrebel插件的安装)

[4.2 打开代理](#4.2 打开代理)

[4.3 设置jrebel离线](#4.3 设置jrebel离线)

五、收获


一、文件上传

演示代码基于上篇博客:SpringMVC之CRUDhttps://blog.csdn.net/weixin_74263417/article/details/132763882?spm=1001.2014.3001.5501

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

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

1.1 导入依赖

导入依赖:

XML 复制代码
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

1.2 配置文件上传解析器

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

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工具类

java 复制代码
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的资源文件,如下:

XML 复制代码
dir=D:/temp/upload/
server=/upload/

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

1.6 添加sql

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

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类中加入以下代码:

java 复制代码
List<Music> listPager(Music music);

1.7 编写PageController类

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

java 复制代码
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如下:

html 复制代码
<%@ 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">
    <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>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控制器中增加文件上传的方法进行配置,要增加的代码如下:

java 复制代码
//文件上传
    @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代码如下:

html 复制代码
<%@ 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层中加入以下代码,如下:

java 复制代码
 //文件下载实现
    @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层中加入以下代码,如下:

java 复制代码
//多文件上传
    @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的使用就到这里,祝大家在敲代码的路上一路通畅!

感谢大家的观看 !

相关推荐
Yaml42 分钟前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事4 分钟前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
残月只会敲键盘4 分钟前
面相小白的php反序列化漏洞原理剖析
开发语言·php
哟哟耶耶4 分钟前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo5 分钟前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
ac-er88886 分钟前
PHP弱类型安全问题
开发语言·安全·php
ac-er88887 分钟前
PHP网络爬虫常见的反爬策略
开发语言·爬虫·php
理想不理想v8 分钟前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫9 分钟前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
山东布谷科技官方12 分钟前
布谷直播源码部署服务器关于数据库配置的详细说明
运维·服务器·数据库·直播系统源码·直播源码·直播系统搭建·直播软件开发