目录
一、文件上传的回顾
1、文件上传的必要前提
2、文件上传的原理分析
3、借助第三方组件实现文件上传
二、springmvc 传统方式的文件上传
1、说明
2、实现步骤
(1)第一步:引入Commons-fileupload 文件上传依赖
(2)第二步:编写 jsp 页面
(3)第三步:编写控制器
(4)第四步:在springmvc.xml中配置文件解析器
3、问题:tomcat不能访问本地服务器上的图片
(1)创建本地目录,配置静态资源不过滤
(2)配置IDEA,勾选相关选项
(3)配置tomcat的server.xml文件
三、springmvc 跨服务器方式的文件上传
1、分服务器的目的
2、准备图片存放 tomcat 服务器
(1)修改默认端口——避免和idea使用tomcat端口重叠
(2)创建文件上传目录
(3)web.xml文件中加入允许读写操作
3、拷贝依赖
4、编写控制器实现上传图片
5、编写JSP + 配置解析器
当 form 表单的 enctype 取值不是默认值后, request.getParameter() 将失效。 enctype=”application/x-www-form-urlencoded” 时,form 表单的正文内容是: key=value&key=value&key=value ,当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成: 每一部分都是 MIME 类型描述的正文
// 请求头报文
POST /fileUpload HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 21382
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryyAeL6Zw1JWwLK8Yc
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: JSESSIONID=2D445DA78CC8A811A7DBA86679E6F6AE
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和commons-io。
commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。
传统方式的文件上传,指的是我们上传的文件和访问的应用存在于同一台服务器上。并且上传完成之后,浏览器可能跳转。
org.apache.commons
commons-io
1.3.2
commons-fileupload
commons-fileupload
1.3.1
/**
* 文件上传的的控制器 * @Version 1.0
*/
@Controller
public class FileUploadController {
/**
* 文件上传
*/
@RequestMapping("/fileUpload")
public String testResponseJson(String picName, MultipartFile uploadFile, HttpServletRequest request) throws Exception {
// 一、定义文件名
String fileName = "";
// 1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
// 2.截取文件扩展名
String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
// 3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
// 4.判断是否输入了文件名
if (!StringUtils.isEmpty(picName)) {
fileName = uuid + "_" + picName + "." + extendName;
} else {
fileName = uuid + "_" + uploadFileName;
}
System.out.println(fileName);
// 二、使用request获取文件路径
ServletContext context = request.getServletContext();
String basePath = context.getRealPath("/uploads");
// 三、解决同一文件夹中文件过多问题
String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
// 四、判断路径是否存在
File file = new File(basePath + "/" + datePath);
if (!file.exists()) {
file.mkdirs();
}
// 五、使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
uploadFile.transferTo(new File(file, fileName));
return "success";
}
}
5242880
注意: 文件上传的解析器 id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他字段也将无法绑定)
上传结果:
JAVA开发SSM为架构的系统时,把图片直接存储到tomcat/webapps下的某个文件中后,启动tomcat后,直接通过URL访问报404错误。
找到tomcat的server.xml文件,在该文件Host节点下加入:
其中path是webapp下的文件夹,docBase是真实图片路径
访问结果:
在实际开发中,我们会有很多处理不同功能的服务器。例如:
分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。
...
...
点击startup.bat,并测试:
在图片存放 tomcat 服务器webapps目录下创建文件上传目录: myserver\myfiles
在tomcat 配置文件conf下,web.xml文件中加入允许读写操作。如下:
default
org.apache.catalina.servlets.DefaultServlet
debug
0
readonly
false
listings
false
1
加入此行的含义是:接收文件的目标服务器可以支持写入操作。文件修改完后,重新启动tomcat服务器
在我们负责处理文件上传的项目中还需添加拷贝文件上传的必备 jar 包
org.apache.commons
commons-io
1.3.2
commons-fileupload
commons-fileupload
1.3.1
com.sun.jersey
jersey-client
1.18.1
package com.test.controller;
/**
* @author swadian
* @date 2021/2/6
* @Version 1.0
* @describetion
*/
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
/**
* 文件上传的的控制器 * @Version 1.0
*/
@Controller
public class FileUploadController {
/**
* 文件上传的服务器地址
*/
public static final String FILESERVERURL = "http://localhost:8090/myserver/myfiles/";
/**
* 文件上传
*/
@RequestMapping("/fileUpload")
public String testResponseJson(String picName, MultipartFile uploadFile, HttpServletRequest request) throws Exception {
// 一、定义文件名
String fileName = "";
// 1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
// 2.截取文件扩展名
String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
// 3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
// 4.判断是否输入了文件名
if (!StringUtils.isEmpty(picName)) {
fileName = uuid + "_" + picName + "." + extendName;
} else {
fileName = uuid + "_" + uploadFileName;
}
System.out.println(fileName);
// 5.创建 sun 公司提供的 jersey 包中的 Client 对象
Client client = Client.create();
// 6.指定上传文件的地址,该地址是 web 路径
WebResource resource = client.resource(FILESERVERURL + fileName);
// 7.实现上传
String result = resource.put(String.class, uploadFile.getBytes());
System.out.println(result);
return "success";
}
}
编写JSP + 在springmvc.xml中配置文件解析器,步骤同传统模式一样。
执行结果:
服务器文件夹目录下可以看到上传文件:
通过浏览器可以访问到目标文件: