springmvc文件上传

就是把客户端(浏览器)的文件保存一份到服务器 说白了就是文件的拷贝

常见的使用场景:上传头像、上传各种照片、上传word、Excel等等文件

文件上传要求

浏览器端要求(通用浏览器的要求)

  • 表单提交方式 post
  • 提供文件上传框(组件) input type=”file”
  • 表单的entype属性必须为 multipart/form-data(没有这个属性值的话, 文件的内容是提交不过去的)

服务器端要求

  1. 获取客户端上传的文件

    1. 准备一个目录存储客户端上传的文件
    2. 将客户端上传的文件写入到准备好的目录中

注意:

  • 若表单使用了 multipart/form-data ,使用原生request.getParameter()去获取参数的时候都为null

我们做文件上传一般会借助第三方组件(jar, 框架 SpringMVC)实现文件上传.

常见的文件上传jar包和框架

​ serlvet3.0(原生的文件上传的API)

​ commons-fileupload : apache出品的一款专门处理文件上传的工具包 (我们肯定不会直接使用)

​ struts2(底层封装了:commons-fileupload)

​ SpringMVC(底层封装了:commons-fileupload)

案例-springmvc 传统方式文件上传

  • 创建Maven工程,添加依赖
<dependencies>
<!--文件上传组件的依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--springmvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
  • 创建前端页面
<h1>一,springmvc传统方式文件上传</h1>
<form action="/file/upload" method="post" enctype="multipart/form-data">
图片: <input type="file" name="upload"/><br/>
图片描述:<input type="text" name="pdesc"/>
<input type="submit" value="上传"/>
</form>
  • 控制器
package com.jwang.controller;

import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* 包名:com.jwang.controller
* @author Leevi
* 日期2020-11-15 08:58
* 服务器端获取客户端上传的文件:
* 1. 在springmvc的配置文件中配置文件解析器,将字节输入流解析成MultipartFile对象
* 2. 在控制器方法中添加MultipartFile类型的参数
*/
@RestController
@RequestMapping("/file")
public class FileController {
@RequestMapping("/upload")
public String upload(MultipartFile upload, String pdesc, HttpSession session) throws IOException {
System.out.println(pdesc);
InputStream is = null;
FileOutputStream out = null;
try {
ServletContext servletContext = session.getServletContext();
// 在部署的项目路径下准备一个upload目录
String realPath = servletContext.getRealPath("upload");
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();
}
//获取文件名
String originalFilename = upload.getOriginalFilename();
// 使用文件输出流将客户端上传的文件输出到指定目录
out = new FileOutputStream(new File(file, originalFilename));

//客户端上传文件的输入流
is = upload.getInputStream();

IOUtils.copy(is, out);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
} finally {
is.close();
out.close();
}
}
}
  • 在springmvc.xml配置文件解析器

    注意:文件上传的解析器id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他字段也将无法绑定)

<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为 5MB -->
<property name="maxUploadSize" value="5242880"></property>
</bean>

案例-springmvc 跨服务器方式的文件上传

分服务器的目的

在实际开发中,我们会有很多处理不同功能的服务器(注意:此处说的不是服务器集群)。 例如:

​ 应用服务器:负责部署我们的应用
​ 数据库服务器:运行我们的数据库
​ 缓存和消息服务器:负责处理高并发访问的缓存和消息
​ 文件服务器:负责存储用户上传文件的服务器。

分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。

img

跨服务器方式的文件上传图解

img

  • 准备两个服务器(默认情况下,tomcat是不允许其他服务器往它里面写入数据的), 修改tomcat的的conf目录下的web.xml, 添加readonly参数为false

img

实现

  • 添jersey依赖 (跨服务器上传图片的代码)
<dependencies>
<!--引入文件上传的依赖-->
<!--文件上传组件的依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--springmvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

<!--跨服务器上传的文件的依赖-->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
</dependencies>
  • 前端页面
<h1>二,springmvc 跨服务器方式的文件上传</h1>
<form action="/file/upload" method="post" enctype="multipart/form-data">
图片: <input type="file" name="upload"/><br/>
图片描述:<input type="text" name="pdesc"/>
<input type="submit" value="上传"/>
</form>
  • 控制器
package com.jwang.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
* 包名:com.jwang.controller
* @author Leevi
* 日期2020-11-15 08:58
* 跨服务器文件上传:
* 1. 使用springmvc的方式获取客户端上传的文件
* 2. 使用跨服务器上传文件的API,将图片上传到文件服务器
*/
@RestController
@RequestMapping("/file")
public class FileController {

/**
* 改成跨服务器文件上传
* @param upload
* @param pdesc
* @return
* @throws IOException
*/
@RequestMapping("/upload")
public String upload(MultipartFile upload, String pdesc) throws IOException {
System.out.println(pdesc);
try {
//获取文件名
String originalFilename = upload.getOriginalFilename();
//上传文件的路径
String uploadPath = "http://localhost:8899/upload/"+originalFilename;

//创建一个文件上传的客户端
Client client = Client.create();
//建立与服务器的连接
WebResource resource = client.resource(uploadPath);
//将文件上传给服务器
resource.put(upload.getBytes());
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
}