一.文件上传
以下实例演示的代码是基于本人博客中的代码进行扩展 : SpringMVC的整合完成CRUD
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>
CommonsMultipartResolver是MultipartResolver接口的实现类
1.3 配置服务器存放文件地址
具体操作如下:
1.3.1.点击编辑Configurations
1.3.2.将项目部署至tomcat服务器上
1.3.3.配置相对路径
注:本地路径名需与resource.properties资源文件中路径保持一致。
1.4.导入PropertiesUtil工具类
package com.junlinyi.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.junlinyi.model.Work" parameterType="com.junlinyi.model.Work" > select * from t_work-zw <where> <if test="dname != null"> and dname like concat('%',#{dname},'%') </if> </where> </select>
紧接着在自动生成的mapper类中加入以下代码:
List<Work> listPager(Work work);
1.7.编写PageController类
然后再创建一个公共路径处理类 PageController类,代码如下:
package com.junlinyi.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; /** * @author junlinyi * @site www.junlinyi.com * @company 君氏集团 * @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"> <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 }/work/list" method="post"> <div class="form-group mb-2"> <input type="text" class="form-control-plaintext" name="dname" 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 }/work/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">职业logo</th> <th scope="col">操作</th> </tr> </thead> <tbody> <c:forEach var="b" items="${lst }"> <tr> <td>${b.did }</td> <td>${b.dname }</td> <td>${b.dwork }</td> <td>${b.dtp }</td> <td> <a href="${pageContext.request.contextPath }/work/preSave?did=${b.did}">修改</a> <a href="${pageContext.request.contextPath }/work/del?did=${b.did}">删除</a> <a href="${pageContext.request.contextPath }/page/work/upload?did=${b.did}">图片上传</a> <a href="${pageContext.request.contextPath }/work/download?did=${b.did}">图片下载</a> </td> </tr> </c:forEach> </tbody> </table> <!-- 这一行代码就相当于前面分页需求前端的几十行了 --> <z:page pageBean="${pageBean }"></z:page> ${pageBean } </body> </html>
1.9.编写文件上传方法
在我们的WorkController控制器中增加文件上传的方法进行配置,要增加的代码如下:
//文件上传 @RequestMapping("/upload") public String upload(Work work,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)); work.setMpic(server+fileName); workBiz.updateByPrimaryKeySelective(work); } 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}/work/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}/work/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(Work work,HttpServletRequest req){ try { //先根据文件id查询对应图片信息 Work work = this.musworkicBiz.selectByPrimaryKey(work.getdid()); String diskPath = PropertiesUtil.getValue("dir"); String reqPath = PropertiesUtil.getValue("server"); String realPath = work.getdtp().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, Work work, 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 启动项目有以下好处:
- 快速部署:JRebel 允许在应用程序运行时热部署代码和资源文件,而无需重新启动整个应用程序。这大大提高了开发效率,省去了传统的重启应用程序的时间。
- 即时生效:JRebel 对于大部分代码和资源的修改,都能够实时生效,无须手动重新编译和重新部署。这使得开发人员能够立即看到他们所做的更改的效果,快速迭代开发。
- 保持应用状态:JRebel 可以保持应用程序的状态,包括各种已经加载的类、对象、变量等。这意味着在代码修改后,应用程序的状态仍然可以保持不变,不会丢失用户的登录状态、缓存数据等。
- 支持多种框架和技术栈:JRebel 不仅适用于 Java SE 和 Java EE 应用程序,还支持许多主流的框架和技术栈,如Spring、Hibernate、Maven、Gradle等。这使得 JRebel 能够应用于各种类型的项目。
- 减少开发周期:由于 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插件启动项目之前就可以不打开代理辅助工具了。