• 【SpringMVC】一行代码完成文件上传&JRebel的使用


    目录

    引言

    一、JRebel的使用

    1.1.安装JReble

    1.2.反向代理工具

    1.3.离线使用

    二、文件上传

    2.1.公共文件跳转

    2.2.添加依赖

    2.3.配置文件上传解析器

     2.4.图片路径配置Tomcat

    2.5.前端代码

    2.6.文件上传实现

    三、文件下载

    3.1.Controller层

    3.2.前端代码

    四、多文件上传

    4.1.Controller层

    4.2.前端代码


    引言

    在以往的写代码过程中,我们肯定会遇到客户有文件上传的需求,写过的同志都知道代码量是有的而且比较繁琐,今天这篇博客就来介绍一个Java库commons-fileupload,该库是Apache的一个开源Java库,它提供了一种简单的方式来上传和处理文件。它是Java Servlet API的一部分,可以方便地在Web应用程序中实现文件上传功能。

    一、JRebel的使用

    在讲解文件上传之前,先向大家推荐一下JRebel的使用,JRebel的主要功能是实现热部署,节省了大量重启时间,提高了个人开发效率。

    1.1.安装JReble

    我这里以IDEA为例,在Settings里点击Plugins在Marketplace处搜索jrebel,选择第一个安装即可。

    安装后重启IDEA即可。

    1.2.反向代理工具

    这里会使用一个反向代理工具ReverseProxy_windows_amd64,而JRebel是一个Java虚拟机插件,它们之间没有直接的关系。但是,如果您在使用JRebel时遇到了问题,可以尝试先启动ReverseProxy_windows_amd64,然后再使用JRebel。

    下载地址
    Release v1.4 · ilanyu/ReverseProxy · GitHub

    下载完成后打开代理ReverseProxy_windows_amd64.exe再jrebel启动项目

    (注意:激活成功前不要关闭反向代理程序)

    选择TeamURL激活

    第一行输入http://127.0.0.1:8888/GUID

    第二行输入电子邮箱即可。

     https://www.guidgen.com/(生成GUID链接)

    1.3.离线使用

    激活后一定要手动切换到离线模式进行使用,过程如图 如下步骤进行操作:

    File ➡Settings➡JRebel ➡Work offline ➡OK

    (注意点击Work offline就会变为Work online)

    下面就可以进行我们的SpringMVC文件上传讲解了。

    二、文件上传

    2.1.公共文件跳转

    该类是方便我们少写重复跳转页面的代码需要跳什么页面jsp的请求上加上/page即可。

    1. @Controller
    2. @RequestMapping("/page")
    3. public class InputController {
    4. @RequestMapping("{page}")
    5. public String to(@PathVariable("page") String page){
    6. return page;
    7. }
    8. @RequestMapping("/{dir}/{page}")
    9. public String todir(@PathVariable("dir") String dir,
    10. @PathVariable("page") String page){
    11. return dir+"/"+page;
    12. }
    13. }

    2.2.添加依赖

    处理文件上传的Java库。

    1. <dependency>
    2. <groupId>commons-fileuploadgroupId>
    3. <artifactId>commons-fileuploadartifactId>
    4. <version>1.3.3version>
    5. dependency>

    2.3.配置文件上传解析器

    将配置文件放入Spring-mvc.xml中

    1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    2. <property name="defaultEncoding" value="UTF-8">property>
    3. <property name="maxUploadSize" value="52428800">property>
    4. <property name="resolveLazily" value="true"/>
    5. bean>

    MultipartResolver是用于处理文件上传,当收到请求时DispatcherServlet的checkMultipart()方法会调用MultipartResolver的isMultipart()方法判断请求中是否包含文件,如果请求数据中包含文件,则调用MultipartResolver的resolverMultipart()方法对请求的数据进行解析,然后将文件数据解析MultipartFile并封装在MultipartHTTPServletRequest(继承了HTTPServletRequest)对象中,最后传递给Controller。  

     2.4.图片路径配置Tomcat

    为了我们的后期维护,所以将本地图片路径与Tomcat访问路径进行配置文件的保存。

    PropertiesUtil.java

    1. public class PropertiesUtil {
    2. public static String getValue(String key) throws IOException {
    3. Properties p = new Properties();
    4. InputStream in = PropertiesUtil.class.getResourceAsStream("/resource.properties");
    5. p.load(in);
    6. return p.getProperty(key);
    7. }
    8. }

    resource.properties

    1. dir=E:/oa/idea/upload/
    2. server=/upload/

     点击菜单栏上的Tomcat选择Edit Configurations

    2.5.前端代码

    list.jsp

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
    3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <link
    8. href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
    9. rel="stylesheet">
    10. <script
    11. src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js">script>
    12. <title>学生管理首页title>
    13. <style type="text/css">
    14. .page-item input {
    15. padding: 0;
    16. width: 40px;
    17. height: 100%;
    18. text-align: center;
    19. margin: 0 6px;
    20. }
    21. .page-item input, .page-item b {
    22. line-height: 38px;
    23. float: left;
    24. font-weight: 400;
    25. }
    26. .page-item.go-input {
    27. margin: 0 10px;
    28. }
    29. style>
    30. head>
    31. <body>
    32. <form class="form-inline"
    33. action="${pageContext.request.contextPath }/student/list" method="post">
    34. <div class="form-group mb-2">
    35. <input type="text" class="form-control-plaintext" name="sname"
    36. placeholder="请输入学生名称">
    37. <%--<input name="pagination" value="false" type="hidden">--%>
    38. div>
    39. <button type="submit" class="btn btn-primary mb-2">查询button>
    40. <a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/student/PreSave">新增a>
    41. form>
    42. <table class="table table-striped ">
    43. <thead>
    44. <tr>
    45. <th scope="col">学生IDth>
    46. <th scope="col">学生名称th>
    47. <th scope="col">学生照片th>
    48. <th scope="col">学生性别th>
    49. <th scope="col">操作th>
    50. tr>
    51. thead>
    52. <tbody>
    53. <c:forEach var="s" items="${slist }">
    54. <tr>
    55. <td>${s.sid }td>
    56. <td>${s.sname }td>
    57. <td>
    58. <img src="${s.sage }" style="width: 50px;height: 50px;">
    59. td>
    60. <td>${s.ssex }td>
    61. <td>
    62. <a href="${pageContext.request.contextPath }/student/PreSave?sid=${s.sid}">修改a>
    63. <a href="${pageContext.request.contextPath }/student/del?sid=${s.sid}">删除a>
    64. <a href="${pageContext.request.contextPath }/page/student/upload?sid=${s.sid}">上传照片a>
    65. td>
    66. tr>
    67. c:forEach>
    68. tbody>
    69. table>
    70. <z:page pageBean="${pageBean }">z:page>
    71. <%--${pageBean }
    72. ${slist}--%>
    73. body>
    74. html>

    upload.jsp 

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>学生照片上传title>
    5. head>
    6. <body>
    7. <form action="${pageContext.request.contextPath }/student/upload" method="post" enctype="multipart/form-data">
    8. <label>学生编号:label><input type="text" name="sid" readonly="readonly" value="${param.sid}"/><br/>
    9. <label>学生图片:label><input type="file" name="simg"/><br/>
    10. <input type="submit" value="上传图片"/>
    11. form>
    12. body>
    13. html>

    2.6.文件上传实现

    StudentController.java

    1. @Controller
    2. @RequestMapping("/student")
    3. public class StudentController {
    4. @Autowired
    5. private StudentBiz stubiz;
    6. // 增
    7. @RequestMapping("/add")
    8. public String add(Student student){
    9. stubiz.insertSelective(student);
    10. return "redirect:list";
    11. }
    12. // 删
    13. @RequestMapping("/del")
    14. public String del(Student student){
    15. stubiz.deleteByPrimaryKey(student.getSid());
    16. return "redirect:list";
    17. }
    18. // 查
    19. @RequestMapping("/list")
    20. public String list(Student student, HttpServletRequest request){
    21. PageBean pageBean=new PageBean();
    22. pageBean.setRequest(request);
    23. List students = stubiz.selectBySnamePager(student, pageBean);
    24. request.setAttribute("slist",students);
    25. request.setAttribute("pageBean",pageBean);
    26. return "student/list";
    27. }
    28. // 改
    29. @RequestMapping("/edit")
    30. public String edit(Student student){
    31. stubiz.updateByPrimaryKeySelective(student);
    32. return "redirect:list";
    33. }
    34. // 模糊分页查询
    35. @RequestMapping("/PreSave")
    36. public String PreSave(Student student, HttpServletRequest request){
    37. if(student!=null && student.getSid()!=null){
    38. Student s = stubiz.selectByPrimaryKey(student.getSid());
    39. request.setAttribute("s",s);
    40. }
    41. return "student/edit";
    42. }
    43. //文件上传
    44. @RequestMapping("/upload")
    45. public String upload(MultipartFile simg,Student student) throws IOException {
    46. //将上传图片保存到服务器中的指定位置
    47. String dir= PropertiesUtil.getValue("dir");
    48. String server=PropertiesUtil.getValue("server");
    49. String filename = simg.getOriginalFilename();
    50. FileUtils.copyInputStreamToFile(simg.getInputStream(),new File(dir+filename));
    51. //将上传的图片保存到数据库
    52. student.setSage(server+ filename);
    53. stubiz.updateByPrimaryKeySelective(student);
    54. return "redirect:list";
    55. }
    56. }

    效果展示:

    这时候查看我们所配置的本地路径中也有图片了。

    三、文件下载

    3.1.Controller层

    StudentController.java

    1. @Controller
    2. @RequestMapping("/student")
    3. public class StudentController {
    4. @Autowired
    5. private StudentBiz stubiz;
    6. // 增
    7. @RequestMapping("/add")
    8. public String add(Student student){
    9. stubiz.insertSelective(student);
    10. return "redirect:list";
    11. }
    12. // 删
    13. @RequestMapping("/del")
    14. public String del(Student student){
    15. stubiz.deleteByPrimaryKey(student.getSid());
    16. return "redirect:list";
    17. }
    18. // 查
    19. @RequestMapping("/list")
    20. public String list(Student student, HttpServletRequest request){
    21. PageBean pageBean=new PageBean();
    22. pageBean.setRequest(request);
    23. List students = stubiz.selectBySnamePager(student, pageBean);
    24. request.setAttribute("slist",students);
    25. request.setAttribute("pageBean",pageBean);
    26. return "student/list";
    27. }
    28. // 改
    29. @RequestMapping("/edit")
    30. public String edit(Student student){
    31. stubiz.updateByPrimaryKeySelective(student);
    32. return "redirect:list";
    33. }
    34. // 模糊分页查询
    35. @RequestMapping("/PreSave")
    36. public String PreSave(Student student, HttpServletRequest request){
    37. if(student!=null && student.getSid()!=null){
    38. Student s = stubiz.selectByPrimaryKey(student.getSid());
    39. request.setAttribute("s",s);
    40. }
    41. return "student/edit";
    42. }
    43. //文件上传
    44. @RequestMapping("/upload")
    45. public String upload(MultipartFile simg,Student student) throws IOException {
    46. //将上传图片保存到服务器中的指定位置
    47. String dir= PropertiesUtil.getValue("dir");
    48. String server=PropertiesUtil.getValue("server");
    49. String filename = simg.getOriginalFilename();
    50. FileUtils.copyInputStreamToFile(simg.getInputStream(),new File(dir+filename));
    51. //将上传的图片保存到数据库
    52. student.setSage(server+ filename);
    53. stubiz.updateByPrimaryKeySelective(student);
    54. return "redirect:list";
    55. }
    56. //文件下载
    57. @RequestMapping(value="/download")
    58. public ResponseEntity<byte[]> download(Student student, HttpServletRequest req){
    59. try {
    60. //先根据文件id查询对应图片信息
    61. Student students = this.stubiz.selectByPrimaryKey(student.getSid());
    62. String diskPath = PropertiesUtil.getValue("dir");
    63. String reqPath = PropertiesUtil.getValue("server");
    64. String realPath = students.getSage().replace(reqPath,diskPath);
    65. String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
    66. //下载关键代码
    67. File file=new File(realPath);
    68. HttpHeaders headers = new HttpHeaders();//http头信息
    69. String downloadFileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");//设置编码
    70. headers.setContentDispositionFormData("attachment", downloadFileName);
    71. headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    72. //MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息
    73. return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
    74. }catch (Exception e){
    75. e.printStackTrace();
    76. }
    77. return null;
    78. }
    79. }

    3.2.前端代码

    list.jsp

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
    3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <link
    8. href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
    9. rel="stylesheet">
    10. <script
    11. src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js">script>
    12. <title>学生管理首页title>
    13. <style type="text/css">
    14. .page-item input {
    15. padding: 0;
    16. width: 40px;
    17. height: 100%;
    18. text-align: center;
    19. margin: 0 6px;
    20. }
    21. .page-item input, .page-item b {
    22. line-height: 38px;
    23. float: left;
    24. font-weight: 400;
    25. }
    26. .page-item.go-input {
    27. margin: 0 10px;
    28. }
    29. style>
    30. head>
    31. <body>
    32. <form class="form-inline"
    33. action="${pageContext.request.contextPath }/student/list" method="post">
    34. <div class="form-group mb-2">
    35. <input type="text" class="form-control-plaintext" name="sname"
    36. placeholder="请输入学生名称">
    37. <%--<input name="pagination" value="false" type="hidden">--%>
    38. div>
    39. <button type="submit" class="btn btn-primary mb-2">查询button>
    40. <a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/student/PreSave">新增a>
    41. form>
    42. <table class="table table-striped ">
    43. <thead>
    44. <tr>
    45. <th scope="col">学生IDth>
    46. <th scope="col">学生名称th>
    47. <th scope="col">学生照片th>
    48. <th scope="col">学生性别th>
    49. <th scope="col">操作th>
    50. tr>
    51. thead>
    52. <tbody>
    53. <c:forEach var="s" items="${slist }">
    54. <tr>
    55. <td>${s.sid }td>
    56. <td>${s.sname }td>
    57. <td>
    58. <img src="${s.sage }" style="width: 50px;height: 50px;">
    59. td>
    60. <td>${s.ssex }td>
    61. <td>
    62. <a href="${pageContext.request.contextPath }/student/PreSave?sid=${s.sid}">修改a>
    63. <a href="${pageContext.request.contextPath }/student/del?sid=${s.sid}">删除a>
    64. <a href="${pageContext.request.contextPath }/page/student/upload?sid=${s.sid}">上传照片a>
    65. <a href="${pageContext.request.contextPath }/student/download?sid=${s.sid}">下载照片a>
    66. td>
    67. tr>
    68. c:forEach>
    69. tbody>
    70. table>
    71. <z:page pageBean="${pageBean }">z:page>
    72. <%--${pageBean }
    73. ${slist}--%>
    74. body>
    75. html>

    效果演示: 

    四、多文件上传

    由于我的数据库表中没有存储多个图片的字段,就不过数据库演示了。

    4.1.Controller层

    1. //多文件上传
    2. @RequestMapping("/uploads")
    3. public String uploads(HttpServletRequest req, Student student, MultipartFile[] files){
    4. try {
    5. StringBuffer sb = new StringBuffer();
    6. for (MultipartFile cfile : files) {
    7. //思路:
    8. //1) 将上传图片保存到服务器中的指定位置
    9. String dir = PropertiesUtil.getValue("dir");
    10. String server = PropertiesUtil.getValue("server");
    11. String filename = cfile.getOriginalFilename();
    12. FileUtils.copyInputStreamToFile(cfile.getInputStream(),new File(dir+filename));
    13. sb.append(filename).append(",");
    14. }
    15. System.out.println(sb.toString());
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. return "redirect:list";
    20. }

    4.2.前端代码

    1. <a href="${pageContext.request.contextPath }/page/student/uploads">多文件上传a>
    2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    3. <html>
    4. <head>
    5. <title>Titletitle>
    6. head>
    7. <body>
    8. <form action="${pageContext.request.contextPath }/student/uploads" method="post" enctype="multipart/form-data">
    9. <input type="file" name="files" multiple>
    10. <button type="submit">上传button>
    11. form>
    12. body>
    13. html>

    效果演示:

    到这里我的分享就结束了,欢迎到评论区探讨交流!!

    💖如果觉得有用的话还请点个赞吧 💖

  • 相关阅读:
    介绍 TensorFlow 的基本概念和使用场景。
    python实现批量数据库数据插入
    Javascript笔记(七)之函数、闭包、生成器、箭头函数
    基于虚拟同步发电机控制的双机并联Simulink仿真模型
    解决MyBatis-Plus updateById方法更新不了空字符串或null
    Elasticsearch生命周期ILM若干时间后自动删除索引index
    Python:用指定的字拼成这个字本身
    java中转义字符的源码数据格式,内存存储数据格式和转换json后的数据格式
    etcd选举源码分析和例子
    如果你项目使用了MyBatis-Plus你一定要用它
  • 原文地址:https://blog.csdn.net/weixin_74318097/article/details/132775259