SpringMvc文件上传下载一条龙服务教会你

简介: SpringMvc文件上传下载一条龙服务教会你



1.前言

什么是SpringMvc框架?

SpringMVC就是一个Spring内置的MVC框架。

MVC框架,它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化等等),而且使用简单,与Spring无缝集成。支持 RESTful风格的URL请求。

什么是SpringMvc框架作用?

Spring MVC框架是Spring框架的一个模块,用于支持Web应用程序的开发。 它采用了MVC(Model-View-Controller)设计模式,将应用程序的业务逻辑、视图和用户请求处理分离,从而提高了应用程序的可维护性、可扩展性和可测试性。

2.文件如何上传

2.1公共文件跳转

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

package com.sy.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * @author 谌艳
 * @site www.shenyan.com
 * @create 2023-09-08 17:18
 */
@Controller
@RequestMapping("/page")
public class InputController {
    @RequestMapping("/{page}")
    public String to(@PathVariable("page") String page){
        return page;
    }
    @RequestMapping("/{dir}/{page}")
    public String to(@PathVariable("dir") String dir,
                     @PathVariable("page") String page){
        return dir+"/"+page;
    }
}

2.2.添加依赖

先导入pom.xml依赖文件,处理文件上传的Java库。

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

2.3.配置文件上传解析器

将配置文件放入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>

2.4.图片路径配置Tomcat

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

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);
  }
}

resource.properties

dir=E:/temp/
server=/temp/

2.5.前端代码

index.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 }/book/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 }/book/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="${list }">
        <tr>
            <td>${b.bid }</td>
            <td>${b.bname }</td>
            <td>
                <img src="${b.bimage }" style="height: 100px;width: 60px" >
            </td>
            <td>${b.price }</td>
            <td>
                <a href="${pageContext.request.contextPath }/book/preSave?bid=${b.bid}">修改</a>
                <a href="${pageContext.request.contextPath }/book/del?bid=${b.bid}">删除</a>
                <a href="${pageContext.request.contextPath }/page/book/upload?bid=${b.bid}">上传图片</a>
                <a href="${pageContext.request.contextPath }/book/download?bid=${b.bid}">下载图片</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>
</body>
</html>

upload.jsp

<%--
  Created by IntelliJ IDEA.
  User: 86177
  Date: 2023/9/9
  Time: 14:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍logo上传</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="xxx"/><br/>
    <input type="submit" value="上传图片"/>
</form>
<form method="post" action="${pageContext.request.contextPath }/book/uploads" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <button type="submit">上传</button>
</form>
</body>
</html>

2.6.文件上传实现

//    文件上传
    @RequestMapping("/upload")
public String upload(Book book,MultipartFile xxx){
        try {
//        上传图片真实存放地址
     String dir = PropertiesUtil.getValue("dir");
//网络访问地址
    String server =PropertiesUtil.getValue("server");
    String filename = xxx.getName();
    System.out.println("文件名:"+filename);
    System.out.println("文件类别:"+xxx.getContentType());
    FileUtils.copyInputStreamToFile(xxx.getInputStream(),new File(dir+filename));
    book.setBimage(server+filename);
    bookBiz.updateByPrimaryKeySelective(book);
        } catch (IOException e) {
        e.printStackTrace();
    }
    return "redirect:list";
}

效果展示:

3.文件下载

3.1.Controller层

//文件图片下载
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(Book book, HttpServletRequest req){
    try {
        //先根据文件id查询对应图片信息
        Book blz = this.bookBiz.selectByPrimaryKey(book.getBid());
        String diskPath = PropertiesUtil.getValue("dir");
        String reqPath = PropertiesUtil.getValue("server");
        String realPath = blz.getBimage().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;
}

3.2.前端代码

index.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 }/book/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 }/book/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="${list }">
        <tr>
            <td>${b.bid }</td>
            <td>${b.bname }</td>
            <td>
                <img src="${b.bimage }" style="height: 100px;width: 60px" >
            </td>
            <td>${b.price }</td>
            <td>
                <a href="${pageContext.request.contextPath }/book/preSave?bid=${b.bid}">修改</a>
                <a href="${pageContext.request.contextPath }/book/del?bid=${b.bid}">删除</a>
                <a href="${pageContext.request.contextPath }/page/book/upload?bid=${b.bid}">上传图片</a>
                <a href="${pageContext.request.contextPath }/book/download?bid=${b.bid}">下载图片</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>
</body>
</html>

效果展示:

4.多文件上传

4.1.Controller层

//多文件上传
    @RequestMapping("/uploads")
    public String uploads(HttpServletRequest req, Book book, 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";
    }

4.2.前端代码

upload.jsp

<%--
  Created by IntelliJ IDEA.
  User: 86177
  Date: 2023/9/9
  Time: 14:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍logo上传</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="xxx"/><br/>
    <input type="submit" value="上传图片"/>
</form>
<form method="post" action="${pageContext.request.contextPath }/book/uploads" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <button type="submit">上传</button>
</form>
</body>
</html>

效果展示:

5.JRebel的使用

5.1.安装JReble

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

安装后重启IDEA即可。

5.2.反向代理工具

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

 

下载地址

选择TeamURL激活

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

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

GUID online erstellen生成GUID链接

5.3.离线使用

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

File ➡Settings➡JRebel ➡Work offline ➡OK

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

                                                       今日分享就到这里结束了哦。                                                    

目录
相关文章
|
2月前
|
XML JSON Java
基于springMVC的RESTful服务实现
  RESTful(RESTful Web Services)一种架构风格,表述性状态转移,它不是一个软件,也不是一个标准,而是一种思想,不依赖于任何通信协议,但是开发时要成功映射到某协议时也需要遵循其标准,但不包含对通信协议的更改
23 1
|
调度 网络架构
|
缓存 JSON 数据安全/隐私保护
|
前端开发 数据库 Spring
maven+SpringMVC搭建RESTful后端服务框架
今天来尝试一下搭建基于SpringMVC的RESTful标准的后端服务。 首先,什么是MVC?M-model,模型,指业务数据层,具体一点就是业务逻辑与数据库的交互;V-view,视图,用来展示数据,传统SpringMVC中控制器有返回类型ModelAndView,即返回含有数据模型与页面视图的jsp文件;C-controller,控制器,通常负责处理与用户间的交互,控制从数据库取数与返回结果到用户等。
1404 0
|
Web App开发 前端开发 Java
|
Java 关系型数据库 MySQL
SpringBoot搭建基于Spring+SpringMvc+Mybatis的REST服务
Maven Plugin管理 通常,让你的Maven POM文件继承 spring-boot-starter-parent,并声明一个或多个 Starter POMs依赖即可。 spring-boot-starter-parent 1 2 org.
1582 0
|
4月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】
|
1月前
|
Java Apache vr&ar
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
16 0
|
6月前
|
前端开发 Java Go
Spring MVC 和 Spring Boot 的区别
Spring MVC 和 Spring Boot 的区别
110 0
|
9月前
|
Java Spring
springmvc中spring提供的中文乱码解决问题
可以解决浏览器的乱码问题
44 0