前言:
本篇文章中的demo是springmvc框架下执行的,对于springmvc框架搭建有不清楚的伙伴可参考博文springMVC项目框架搭建详解
以下例子中,上传的图片存放地址在tomcat服务器中,
相对路径为:webapps/项目名称/uploads/
说明
1、文件上传的必要前提
- form 表单的 enctype 取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型 - method 属性取值必须是 Post
- 提供一个文件选择域
2、借助第三方组件实现文件上传
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和commons-io。
commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。
传统方式文件上传(古老)
传统方式指的是我们上传的文件和访问的应用存在于同一台服务器上。并且上传完成之后,浏览器可能跳转。
1、导入文件上传的jar包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2、js代码
<h3>传统方式文件上传</h3>
<br>
<form action="file/testFile" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload">
<input type="submit" value="上传">
</form>
3、后台代码
@Controller
@RequestMapping("/file/")
public class FileController {
/**
* @param request
* @return :java.lang.String
* @ Describe : 传统方式文件上传
* @ Author : zhy
**/
@RequestMapping(value = "testFile", method = RequestMethod.POST)
public String testFile(HttpServletRequest request) throws Exception {
System.out.println("传统方式文件上传");
// 使用fileupload组件完成文件上传
// 上传位置
String realPath = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断该路径是否存在
File file = new File(realPath);
if (!file.exists()) {
// 创建该文件夹
file.mkdirs();
}
// 解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request
List<FileItem> fileItems = upload.parseRequest(request);
// 遍历
for (FileItem fi :
fileItems) {
// 进行判断,当前item对象是否是上传文件项
if (fi.isFormField()) {
// 说明普通表单项
} else {
// 说明上传文件项
// 获取上传文件的名称
String fileName = fi.getName();
// 把文件名称设置为唯一的值,uuid
String replace = UUID.randomUUID().toString().replace("-", "");
fileName = replace + "_" + fileName;
// 完成文件上传
fi.write(new File(realPath, fileName));
// 删除临时文件
fi.delete();
}
}
return "success";
}
}
springMVC中传统方式文件上传
SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。
1、导入文件上传的jar包
与上一个方式中导入的jar包一样
2、js代码
这里设置file标签的name属性为upload,当在配置MultipartFile对象时,需要使用相同的名称。
<h3>SpringMVC文件上传</h3>
<br>
<form action="file/testFile2" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload">
<input type="submit" value="上传">
</form>
3、后台代码
后台中方法的参数会用到MulitpartFile类型的对象,而这个对象的名称,必须和js代码中file标签的name属性值一样。
/**
* @param request
* @return :java.lang.String
* @ Describe : springMVC文件上传方式
* @ Author : zhy
**/
@RequestMapping(value = "/file/testFile2", method = RequestMethod.POST)
public String testFile2(HttpServletRequest request, MultipartFile upload) throws Exception {
System.out.println("springMVC文件上传方式");
// 使用fileupload组件完成文件上传
// 上传位置
String realPath = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断该路径是否存在
File file = new File(realPath);
if (!file.exists()) {
// 创建该文件夹
file.mkdirs();
}
// 说明上传文件项
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 把文件名称设置为唯一的值,uuid
String replace = UUID.randomUUID().toString().replace("-", "");
filename = replace + "_" + filename;
// 完成文件上传
upload.transferTo(new File(realPath,filename));
return "success";
}
4、配置文件解析器对象
文件解析器对象的id名称是固定值,为multipartResolver
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
跨服务器方式上传文件
目的:
在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
缓存和消息服务器:负责处理大并发访问的缓存和消息
文件服务器:负责存储用户上传文件的服务器。
所以当用户在使用应用服务器进行文件上传时,就需要将文件上传到文件服务器中,这时就用需要进行跨服务器方式实现文件上传。
实例中需要两台tomcat服务器,其中一台为项目本身运行的服务器,另一个需要我们自己再搭建一个tomcat服务器。
1、另一台服务器配置
新建一个springMVC的web工程项目,将此项目部署到tomcat服务器上。具体操作请参考博文:springMVC项目框架搭建详解
本例中创建另一个新项目名称:fileuploadserver
2、进行tomcat服务器的相关配置
找到tomcat安装目录中的web.xml文件
在其内部的servlet标签中加入如下内容:
<!--允许文件写入-->
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
加入这个标签后,可以是目标服务器支持写入操作。
3、导入jar包
<!-- 跨服务器方式上传文件-->
<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>
js代码
<h3>跨服务器文件上传</h3>
<br>
<form action="file/testFile3" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload">
<input type="submit" value="上传">
</form>
后台代码
/**
* @ Describe : 跨服务器方式上传文件
* @ Author : zhy
* @param upload
* @return :java.lang.String
**/
@RequestMapping(value = "testFile3")
public String testFile3(MultipartFile upload) throws Exception {
System.out.println("跨服务器方式上传文件");
// 定义上传文件服务器路径(这个路径和端口是自己在创建项目搭建tomcat服务器时配置的)
String path="http://localhost:8081/fileuploadserver_war/uploads/";
// 说明上传文件项
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 把文件名称设置为唯一的值,uuid
String replace = UUID.randomUUID().toString().replace("-", "");
filename = replace + "_" + filename;
// 创建客户端的对象
Client client= Client.create();
// 链接图片服务器
WebResource webResource=client.resource(path+filename);
// 上传文件
webResource.put(upload.getBytes());
//跳转页面
return "success";
}
添加文件
在后台代码中需要定义上传文件的服务器路径,所以我们需要保证我们的目标服务器项目中有这个文件路径。
在本例中,需要在新建的目标项目中的相关目录中包含uploads文件:
D:\allproject\fileuploadserver\target\fileuploadserver\uploads