前言
当涉及到Web应用程序的开发时,文件上传和下载是非常常见的功能。在SpringMVC框架中,我们可以很方便地实现这些功能。同时,我们还可以使用JRebel来提高开发效率。本文将介绍如何在SpringMVC中实现文件上传和下载,并提供JRebel的下载和使用方法。
一、JRebel的使用
JRebel通过在运行时重新加载修改后的类文件,实现了热部署的功能。它能够监测到代码的变化,并将变化应用到正在运行的应用程序中,从而避免了重新编译和部署的过程。
1.IDea内安装插件
File➡Settings➡plugins➡搜索jrebel
下载后需重启idea才可使用
2.激活
下载服务,进入GitHub网址Release v1.4 · ilanyu/ReverseProxy · GitHub
双击进入服务
打开服务后,在激活完成前不要关闭
开始激活
Team URL第一行:
将GUID替换为GUID online erstellen将GUID替换为将GUID替换为GUID online erstellen所生成的GUID链接
第二行填入电子邮箱即可
然后将最下面的勾选上并点击Active JRebel进行激活
这样就激活成功啦!!
3.离线使用
File➡Settings➡JRebel➡Work office
这样就完成啦,将服务关闭也可继续使用!
使用JRebel的优势
- 提高开发效率:传统的Java开发需要每次修改代码后重新编译和部署应用程序,这样会浪费大量的时间。而使用JRebel,你可以立即看到代码的变化效果,无需重启应用程序,大大提高了开发效率。
- 快速调试和测试:JRebel可以实时加载修改后的代码,使得你可以立即进行调试和测试。你可以在不中断应用程序运行的情况下,快速定位和修复问题,提高调试效率。
- 减少开发周期:由于不需要重启应用程序,使用JRebel可以减少开发周期。你可以更快地完成功能开发和调试,提前交付产品。
- 提高开发体验:JRebel可以让你专注于代码编写,而不需要频繁地重启应用程序。这样可以提高开发的流畅性和舒适度,让你更加享受编码的过程。
- 支持多种框架和服务器:JRebel支持多种Java框架和服务器,包括Spring、Hibernate、Tomcat等。无论你使用哪种框架和服务器,都可以享受到JRebel带来的好处。
二、文件上传与下载
1 .导入pom依赖
添加文件上传依赖
<commons-fileupload.version>1.3.3</commons-fileupload.version> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency>
配置了一个名为"multipartResolver"的Bean,用于处理文件上传。通过设置"defaultEncoding"属性、"maxUploadSize"属性和"resolveLazily"属性,可以指定文件上传时的字符编码、最大上传大小和延迟文件解析的行为。这样,Spring框架在处理文件上传时会根据这些配置进行相应的解析和限制。
<!-- 处理文件上传下载问题 --> <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>
配置表信息,并生成代码
generatorConfig.xml :
<table schema="" tableName="t_user_head" domainObjectName="User" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false"> </table>
4.配置文件
配置文件上传下载路径信息
resource.properties:
#本地路径 dir=D:/temp/upload/ #服务器路径 server=/upload/
编写读取配置文件的工具类
package com.ctb.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); } }
配置文件映射路径
5.前端jsp页面
首页
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/common/header.jsp"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户列表</title> </head> <body> <form class="form-inline" action="/user/list" method="post"> <div class="form-group mb-2"> <input type="text" class="form-control-plaintext" name="uname" placeholder="请输入用户名称"> </div> <button type="submit" class="btn btn-primary mb-2">查询</button> <a class="btn btn-primary mb-2" href="/user/detail">新增</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> </tr> </thead> <tbody> <c:forEach var="b" items="${lst }"> <tr> <td>${b.id }</td> <td>${b.uname }</td> <td> <img src="${b.upic }" style="height: 100px" width="60px"> </td> <td> <a href="/user/detail?id=${b.id}">修改</a> <a href="/user/del/${b.id}">删除</a> <a href="/page/user/upload?id=${b.id}">文件上传</a> <a href="/user/download?id=${b.id}">文件下载</a> </td> </tr> </c:forEach> </tbody> </table> <!-- 这一行代码就相当于前面分页需求前端的几十行了 --> <z:page pageBean="${pageBean }"></z:page> </body> </html>
文件上传表单
<%-- Created by IntelliJ IDEA. User: 86155 Date: 2023/9/9 Time: 15:52 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>头像上传</title> </head> <body> <form action="/user/upload" method="post" enctype="multipart/form-data"> <label>用户编号:</label><input type="text" name="id" readonly="readonly" value="${param.id}"/><br/> <label>用户头像:</label><input type="file" name="uu"/><br/> <input type="submit" value="上传图片"/> </form> <%--多文件上传--%> <form method="post" action="/user/uploads" enctype="multipart/form-data"> <input type="file" name="files" multiple> <button type="submit">上传</button> </form> </body> </html>
6.controller层
package com.ctb.controller; import com.ctb.biz.UserBiz; import com.ctb.model.User; import com.ctb.utils.PageBean; import com.ctb.utils.PropertiesUtil; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; 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; @Controller @RequestMapping("/user") public class UserController { @Autowired private UserBiz userBiz; // 增 @RequestMapping("/add") public String add(User user){ int i = userBiz.insertSelective(user); return "redirect:list"; } // 删 @RequestMapping("/del/{id}") public String del(@PathVariable("id") Integer id){ userBiz.deleteByPrimaryKey(id); return "redirect:/user/list"; } // 改 @RequestMapping("/edit") public String edit(User user){ userBiz.updateByPrimaryKeySelective(user); return "redirect:list"; } @RequestMapping("/upload") public String upload(User user,MultipartFile uu){ try { //上传图片本地路径 String dir= PropertiesUtil.getValue("dir"); //网络访问地址 String server=PropertiesUtil.getValue("server"); //文件名 String filename = uu.getOriginalFilename(); //文件类别 // String type = uu.getContentType(); FileUtils.copyInputStreamToFile(uu.getInputStream(),new File(dir+filename)); user.setUpic(server+filename); userBiz.updateByPrimaryKeySelective(user); } catch (IOException e) { e.printStackTrace(); } return "redirect:list"; } //多文件下载 @RequestMapping("/uploads") public String uploads(HttpServletRequest req, User user, 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"; } // 查 @RequestMapping("/list") public String list(User user, HttpServletRequest request){ PageBean pageBean = new PageBean(); pageBean.setRequest(request); List<User> Users = userBiz.listPager(user, pageBean); request.setAttribute("lst",Users); request.setAttribute("pageBean",pageBean); return "user/list"; } // 查询单个 @RequestMapping("/detail") public String preSave(User user, Model model){ if(user != null && user.getId() != null && user.getId() != 0){ User u = userBiz.selectByPrimaryKey(user.getId()); model.addAttribute("b",u); } return "user/edit"; } @RequestMapping(value="/download") public ResponseEntity<byte[]> download(User user,HttpServletRequest req){ try { //先根据文件id查询对应图片信息 User u = this.userBiz.selectByPrimaryKey(user.getId()); String diskPath = PropertiesUtil.getValue("dir"); String reqPath = PropertiesUtil.getValue("server"); System.out.println(diskPath); String realPath = u.getUpic().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; } }
7.测试结果
文件上传
文件下载
多文件上传