前言:
我们之前已经实现了SpringMVC的增删改查,今天这一篇博客教会您SpringMVC文件上传、下载,多文件上传及工具jrebel的使用,希望这篇博客能够给正在学习,工作的您带来帮助!!!
一.文件上传
1.导入依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
2.配置文件上传解析器
在spring-mvc.xml文件中添加文件上传解析器。
3.配置文件上传解析器
在WEB-INF目录下的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>
CommonsMultipartResolver是MultipartResolver接口的实现类。
MultipartResolver是用于处理文件上传,当收到请求时DispatcherServlet的checkMultipart()方法会调用MultipartResolver的isMultipart()方法判断请求中是否包含文件,如果请求数据中包含文件,则调用MultipartResolver的resolverMultipart()方法对请求的数据进行解析,然后将文件数据解析MultipartFile并封装在MultipartHTTPServletRequest(继承了HTTPServletRequest)对象中,最后传递给Controller。
- MultipartResolver
public interface MultipartResolver { //判断是否存在文件流 boolean isMultipart(HttpServletRequest var1); //解析http请求,并将请求封装到MultipartHttpServletRequest对象中 MultipartHttpServletRequest resolveMultipart(HttpServletRequest var1) throws MultipartException; //清理上传的资源 void cleanupMultipart(MultipartHttpServletRequest var1); }
4.表单设置
表单提交方式为method="post"和enctype="multipart/form-data"
<form action="${ctx}/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="cfile"/><br/> <input type="submit" value="上传图片"/> </form>
项目部署到服务器上(发布项目)
5.文件上传实现
.resource.properties文件
dir=D:/Temp/upload/
server=/upload/
@RequestMapping("/upload") public String upload(HttpServletRequest req, Clazz clazz, MultipartFile cfile){ try { //思路: //1) 将上传图片保存到服务器中的指定位置 String dir = PropertiesUtil.getValue("dir"); String server = PropertiesUtil.getValue("server"); String filename = cfile.getOriginalFilename(); FileUtils.copyInputStreamToFile(cfile.getInputStream(),new File(dir+filename)); //2) 更新数据库表t_struts_class图片记录 clazz.setPic(server+ filename); clazzBiz.updateByPrimaryKeySelective(clazz); } catch (Exception e) { e.printStackTrace(); } return "redirect:list"; }
编写前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>图片上传</title> </head> <body> <form action="${pageContext.request.contextPath }/book/upload" method="post" enctype="multipart/form-data"> <label>书籍编号:</label><input type="text" name="bid" readonly="readonly" value="${param.bid}"/><br/> <label>书籍图片:</label><input type="file" name="bfile"/><br/> <input type="submit" value="上传图片"/> </form> </body> </html>
二.文件下载
1.在controller层加入以下代码
@RequestMapping(value="/download") public ResponseEntity<byte[]> download(HBook hBook, HttpServletRequest req){ try { //先根据文件id查询对应图片信息 HBook clz = this.hBookbiz.selectByPrimaryKey(hBook.getBid()); String diskPath = PropertiesUtil.getValue("dir"); String reqPath = PropertiesUtil.getValue("server"); String realPath = clz.getImg().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; }
三.多文件上传
多文件上传和普通文件上传的区别在于多文件上传可以提高上传效率,减少了选择和上传文件的次数。而普通文件上传只能一次上传一个文件,适用于只需要上传单个文件的场景。
@RequestMapping("/uploads") public String uploads(HttpServletRequest req, HBook hBook, 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"; }
前台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"> <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="bname" 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.bid }</td> <td>${b.bname }</td> <td>${b.price }</td> <td><img src="${b.pic }" style="height: 50px; width: 20px"> </td> <td> <a href="${pageContext.request.contextPath }/clz/preSave?bid=${b.bid}">修改</a> <a href="${pageContext.request.contextPath }/clz/del?bid=${b.bid}">删除</a> <a href="${pageContext.request.contextPath }/page/clz/upload?bid=${b.bid}">上传图片</a> <a href="${pageContext.request.contextPath }/page/clz/download?bid=${b.bid}">下载</a> </td> </tr> </c:forEach> </tbody> </table> <!-- 这一行代码就相当于前面分页需求前端的几十行了 --> <z:page pageBean="${pageBean }"></z:page> </body> </html>
四,jrebel的介绍
1.jrebel是什么?
JRebel 是一个Java 开发工具,它可以避免在进行Java应用程序开发时频繁的重新部署和重启,从而提高开发效率。并保持应用程序状态,使开发过程更加顺畅和高效。
2.如何在idea中安装使用?
安装:打开idea--》File--》Settings--》Plugins--》在Marketplace中搜索
下载好了重启idea
按照顺序:先打开代理ReverseProxy_windows_amd64.exe
使用jrebel启动项目
根据JRebel注册
设置离线:打开idea--》File--》Settings--》JRebel & XRebel