一、异步上传
之前的上传方案,在上传成功后都会跳转页面。而在实际开发中,很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如:上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。
1.1 JSP页面
编写JSP页面,引入jQuery和jQuery表单上传工具jquery.form.js【该js文件已经上传到我的资源,有需要的小伙伴可以自行下载】
upload4.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传</title>
<script src="/js/jquery-2.1.1.min.js"></script>
<script src="/js/jquery.form.js"></script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data">
<input type="file" name="file"/>
<%-- 按钮类型不能是submit,否则会刷新页面 --%>
<input type="button" value="上传头像" id="btn"/>
<!-- 上传头像后展示的位置 -->
<img src="/" width="100" id="img">
<script>
$(function () {
$("#btn").click(function () {
// 异步提交表单
$("#ajaxForm").ajaxSubmit({
url: "/fileUpload4",
type: "post",
success: function (data) {
$("#img").attr("src", data);
console.log(data);
}
})
})
})
</script>
</form>
</body>
</html>
1.2 控制器方法
代码语言:javascript复制// 接收异步上传请求
@RequestMapping("/fileUpload4")
// 不进行页面跳转
@ResponseBody
public String upload3(HttpServletRequest request,MultipartFile file) throws Exception{
// 1.设置上传文件保存的文件夹,存放上传的文件
String realPath = request.getSession().getServletContext().getRealPath("/upload");
File dir = new File(realPath);
if(!dir.exists()){
dir.mkdirs();
}
// 拿到上传文件名
String filename = file.getOriginalFilename();
filename = UUID.randomUUID() "_" filename;
// 创建空文件
File newFile = new File(dir,filename);
// 将上传的文件写到空文件中
file.transferTo(newFile);
System.out.println("/upload/" filename);
return "/upload/" filename;
}
1.3 测试结果
访问路径:http://localhost:8080/upload4.jsp
点击这里查看运行结果
OK,我们可以看得出来确实只刷新了头像那一部分的页面。本次案例成功实现
二、跨服务器上传
由于文件占据磁盘空间较大,在实际开发中往往会将文件上传到其他服务器中,此时需要使用跨服务器上传文件。
2.1 修改tomcat的部分配置
1. 解压tomcat作为图片服务器,在tomcat的webapps下创建upload目录作为文件上传目录。
这是我自己的tomcat安装目录,新建一个upload文件夹。
2. 修改tomcat的 conf/web.xml 文件,支持跨服上传。
代码语言:javascript复制<servlet>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
3. 修改tomcat的 conf/server.xml 文件,修改tomcat端口,修改完开启tomcat服务器,如下图:
代码语言:javascript复制<Connector port="8081" protocol="HTTP/1.1"connectionTimeout="20000" redirectPort="8443" />
双击运行
添加描述
出现该页面,不要关闭这个页面!!!
2.2 JSP页面
代码语言:javascript复制这里的内容和上面的JSP没有区别!只是响应的路径不一样。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传</title>
<script src="/js/jquery-2.1.1.min.js"></script>
<script src="/js/jquery.form.js"></script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data">
<input type="file" name="file"/>
<%-- 按钮类型不能是submit,否则会刷新页面 --%>
<input type="button" value="上传头像" id="btn"/>
<!-- 上传头像后展示的位置 -->
<img src="/" width="100" id="img">
<script>
$(function () {
$("#btn").click(function () {
// 异步提交表单
$("#ajaxForm").ajaxSubmit({
url: "/fileUpload5",
type: "post",
success: function (data) {
$("#img").attr("src", data);
console.log(data);
}
})
})
})
</script>
</form>
</body>
</html>
2.3 添加依赖
代码语言:javascript复制这里我们需要在pom.xml添加跨服上传依赖
<!-- 跨服上传 -->
<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>
2.4 控制器方法
代码语言:javascript复制创建控制器方法,该方法在接受到上传请求后将文件保存到其他服务器上。
// 该方法接收到上传请求后将文件保存到其他服务器上
@RequestMapping("/fileUpload5")
@ResponseBody
public String upload4(HttpServletRequest request,MultipartFile file) throws Exception{
// 设置跨服上传的服务器路径
String path = "http://localhost:8081/upload/";
// 获取上传的文件名
String filename = file.getOriginalFilename();
filename = UUID.randomUUID() "_" filename;
// 跨服上传:
// 1.创建客户端对象
Client client = Client.create();
// 2.使用客户端对象连接图片服务器
WebResource resource = client.resource(path filename);
// 3.传输数据
resource.put(file.getBytes());
System.out.println(path filename);
return path filename;
}
2.5 测试结果
访问路径:http://localhost:8080/upload5.jsp
点击这里查看运行结果
添加描述
出现该页面,不要关闭这个页面!!!
2.2 JSP页面
代码语言:javascript复制这里的内容和上面的JSP没有区别!只是响应的路径不一样。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传</title>
<script src="/js/jquery-2.1.1.min.js"></script>
<script src="/js/jquery.form.js"></script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data">
<input type="file" name="file"/>
<%-- 按钮类型不能是submit,否则会刷新页面 --%>
<input type="button" value="上传头像" id="btn"/>
<!-- 上传头像后展示的位置 -->
<img src="/" width="100" id="img">
<script>
$(function () {
$("#btn").click(function () {
// 异步提交表单
$("#ajaxForm").ajaxSubmit({
url: "/fileUpload5",
type: "post",
success: function (data) {
$("#img").attr("src", data);
console.log(data);
}
})
})
})
</script>
</form>
</body>
</html>
2.3 添加依赖
代码语言:javascript复制这里我们需要在pom.xml添加跨服上传依赖
<!-- 跨服上传 -->
<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>
2.4 控制器方法
代码语言:javascript复制创建控制器方法,该方法在接受到上传请求后将文件保存到其他服务器上。
// 该方法接收到上传请求后将文件保存到其他服务器上
@RequestMapping("/fileUpload5")
@ResponseBody
public String upload4(HttpServletRequest request,MultipartFile file) throws Exception{
// 设置跨服上传的服务器路径
String path = "http://localhost:8081/upload/";
// 获取上传的文件名
String filename = file.getOriginalFilename();
filename = UUID.randomUUID() "_" filename;
// 跨服上传:
// 1.创建客户端对象
Client client = Client.create();
// 2.使用客户端对象连接图片服务器
WebResource resource = client.resource(path filename);
// 3.传输数据
resource.put(file.getBytes());
System.out.println(path filename);
return path filename;
}
2.5 测试结果
访问路径:http://localhost:8080/upload5.jsp
添加描述
可以看得到确实成功上传到了服务器上面的upload目录下
三、文件下载
将文件上传到服务器后,有时我们需要让用户下载上传的文件,接下来我们编写文件下载功能:
3.1 查询可下载文件方法
代码语言:javascript复制编写控制器方法,查询所有可下载的文件(我这里是查询存放在/webapps/upload/目录下的图片),并跳转到下载页面
// 查询可下载的文件
@RequestMapping("/showFiles")
public String showFileDown(HttpServletRequest request, Model model){
// 1.获取下载文件路径集合。注:跨服务器上传中,网络路径无法获取文件列表。
String path = request.getSession().getServletContext().getRealPath("/upload");
File file = new File(path);
String [] files = file.list();
// 2.将路径放入模型中,跳转到JSP页面
model.addAttribute("files",files);
return "download";
}
3.2 添加JSTL依赖
代码语言:javascript复制 <!-- 添加JSTL依赖 -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
3.3 编写下载页面
代码语言:javascript复制<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载</title>
</head>
<body>
<h3>文件下载</h3>
<%-- 遍历文件集合 --%>
<c:forEach items="${files}" var="file">
<a href="/download?fileName=${file}">${file}</a><br/>
</c:forEach>
</body>
</html>
3.4 下载控制器方法
代码语言:javascript复制 // 文件下载
@RequestMapping("/download")
public void fileDown(HttpServletRequest request, HttpServletResponse response,String fileName) throws Exception{
// 设置响应头
response.setHeader("Content-Disposition","attachment;filename=" fileName);
// 获取文件路径
String path = request.getSession().getServletContext().getRealPath("/upload");
File file = new File(path,fileName);
// 获取字节输出流
ServletOutputStream os = response.getOutputStream();
// 使用输出流写出文件
os.write(FileUtils.readFileToByteArray(file));
os.flush();
os.close();
}
3.5 测试结果
OK,我们先来访问http://localhost:8080/showFiles 查询出所有可以下载的文件:然后点击下载也是可以成功下载,文件的上传和下载就学习到这里了。
点击这里查看运行结果
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!