SpringMVC之文件上传下载

目录

1.文件上传

1.1.导入数据表

1.2.添加依赖

1.3.配置文件上传解析器

1.4.表单设置

1.5.文件上传实现

文件下载



1.文件上传

1.1.导入数据表

复制代码
create table t_file
(
  file_id varchar(32) primary key,
  real_name varchar(50) not null,
  content_type varchar(50) not null,
  url varchar(256) not null,
  update_datetime timestamp NULL default CURRENT_TIMESTAMP    -- insert=false
);

1.2.添加依赖

复制代码
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

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

1.4.表单设置

表单提交方式为method="post"和enctype="multipart/form-data"

复制代码
<h1>文件上传</h1>
<form action="${ctx}/bookFile/upload" method="post" enctype="multipart/form-data">
    <label>书本编号:</label><input type="text" name="bookId" readonly="readonly" value="${param.bookId}"/><br/>
    <label>书本图片:</label><input type="file" name="bFile"/><br/>
    <input type="submit" value="上传图片"/>
</form>

1.5.文件上传实现

总之一句话:文件从哪里来(读流),放哪里去(写流)。

  • 创建BookFileVo类

这里需要创建BookFileVo类用于接收前端传递的上传文件信息。

该类中的属性名称必须与前端页面中的表单元素中的name属性一致。

复制代码
@Data
public class BookFileVo extends BookFile {
    private Integer bookId;
    private MultipartFile bFile;
}
  • 创建BookFileController
复制代码
/**
* 文件上传
* @return
*/
@RequestMapping("/upload")
public String upload(HttpServletRequest req,BookFileVo bookFileVo){
    try {
        MultipartFile bFile = bookFileVo.getBFile();
        //思路:
        //1) 将上传图片保存到服务器中的指定位置
        //2) 往数据库表t_book_file中插入一条图片上传记录信息
        //3) 根据书本ID修改书本信息表t_book对应的book_image字段
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "redirect:/book/queryBookPager";
}

文件下载

ResponseEntity标识整个http相应:状态码、头部信息以及相应体内容。因此我们可以使用其对http响应实现完整配置。

如果需要使用ResponseEntity,必须在请求点返回,通常在spring rest中实现。ResponseEntity是通用类型,因此可以使用任意类型作为响应体:

复制代码
@GetMapping("/hello")
ResponseEntity<String> hello() {
    return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}

文件下载实现:

复制代码
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(@RequestParam String fileId){
​
   //1.先根据文件id查询对应图片信息
​
   //2.下载关键代码
   File file=new File(bookFile.getUrl());
   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);
}
相关推荐
Flynn Liang6 小时前
Spring AI 上生产:限流熔断、密钥与成本治理、私有化/混合部署、降级与 Prompt 灰度架构全解
人工智能·spring·架构·高可用·springai·成本治理·生产架构
Flynn Liang7 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
liangbo79 小时前
Spring系列01:IoC 与 DI 到底解决了什么
java·spring
杨凯凡10 小时前
Spring Boot 的 @Transactional 为什么会失效?从代理、自调用到异常回滚的排查实战
java·spring boot·spring·事务·后端开发
哦虎!11 小时前
【JavaEE进阶】SpringBoot
spring
霸道流氓气质1 天前
AI 流式对话与实时聊天平台:SSE 解码竞态、有状态会话隔离与背压取消的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
frjc1 天前
Spring AI 高级实战:ChatMemory、Tool Calling 与 MCP 架构解析
人工智能·spring·架构
T量子永生1 天前
Unisoc(紫光展锐) Kernel 6.18 DDK 编译框架详解
linux·运维·spring
麻瓜code1 天前
Spring AI 全模块 API 字典一览(1.1.0 版)
人工智能·windows·spring
养军博客1 天前
Spring Security 4.x / 5.x / 6.x 配置全对比:前后端不分离与前后端分离
java·后端·spring·springsecurity