Javaweb学习笔记(文件上传和下载)
文件上传
文件上传概述
多数文件上传都是通过表单形式进行提交给后台服务器的,因此要实现文件上传功能,就需要提供一个文件上传的表单。而该表单必须满足
1.form表单的method属性设置为post。
2.form表单的enctype属性设置为multipart/form-data。
3.提供< input type=“file” name=“filename”/>文件上传输入框
文件上传表单的示例代码:
<form action="uploadUrl" method="post" enctype="multipart/form-data">
<input type="file" name="filename" multiple="miltiple" />
<input type="submit" value="文件上传" />
</form>
当客户端form表单的属性为multipart/form-data时浏览器就会采用二进制流的方式来处理表单的数据,服务器端就会对文件上传的请求进行解析处理。Spring MVC为文件上传提供了直接的支持,这种支持是通过MultipartResolver对象实现的。在Spring MVC中使用MultipartResolver对象只需要在配置文件中定义MultipartResolver接口的Bean。
就提配置方式如下:
<bean id="multipartResolver" class=
"org.springframework.web.mutipart.commons.CommonsMultipartResolver">
<!--设置请求编码格式,必须与JSP中的pageEncoding属性一致,默认为ISO-8859-1-->
<property name="defaultEncoding" value="utf-8"/>
<!--设置允许上传文件的最大值,单位为字节--->
<property name="maxUploadSize" value="2097152"/>
......
</bean>
通过< property>元素可以对文件解析器类CommonsMultipartResolver的如下属性进行配置
1.maxUploadSize:上传文件最大长度
2.maxMemorySize:缓存中的最大尺寸
3.dafaultEncoding:默认编码格式
4.resolveLazily:推迟文件解析,以便在Controller中捕获文件大小异常
使用SpringMVC上传文件还需要引入commons-fileupload-1.3.2.jar和common-io-2.5.jar包
当完成页面表单和文件上传解析器的配置后在Controller中编写文件上传的方法。示例代码如下:
@Controller
public class FileUploadController{
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParm("name") String name, @RequestParam("filename") MultipartFile file...){
if(!file.isEmpty()){
...
return "uploadSuccess";
}
return "uploadFailure";
}
}
MultipartFile接口提供了以下方法
方法 | 说明 |
---|---|
byte[] getBytes() | 以字节数组的形式返回文件的内容 |
String getContentType() | 返回文件的内容类型 |
InputStream getInputStream() | 读取文件内容,返回一个InputStream流 |
String getName | 获取多部件form表单的参数名称 |
String getOrignalFilename() | 获取上传文件的初始名 |
long getSize() | 获取上传文件的大小,单位是字节 |
boolean isEmoty() | 判断上传的文件 是够为空 |
void transferTo(File file) | 将上传文件保存到目标目录下 |
应用案例——文件上传
(1)在Eclipse中创建一个wenjian的Web工程,将SpringMVC所需的包以及支持文件下载的JAR包导入
(2)在web.xml文件中,配置SpringMVC的前端控制器信息
(3)在src目录下创建并编写SpringMVC的核心配置文件springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-mvc.xsd">
<context:component-scan base-package="com.itheima.controller"/>
<mvc:annotation-driven/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
</bean>
</beans>
(4)在webContent目录下创建一个用于上传文件的页面fileUpload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
<script >
function check(){
var name=document.getElementById("name").value;
var file=document.getElementById("file").value;
if(name==""){
alert("填写上传人");
return false;
}
if(file.length==0||file==""){
alert("请选择上传文件");
return false;
}
return true;
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath }/fileUpload" method="post" enctype="multipart/form-data" onsubmit="return check()">
上传人:<input id="name" type="text" name="name"/><br>
请选择文件:<input id="file" type="file" name="uploadfile" multiple="multiple"><br>
<input type="submit" value="上传"/>
</form>
</body>
</html>
(5)在WEB-INF创建jsp文件夹,创建success.jsp和error.jsp
(6)在src目录下穿件一个com.itheima.controller包,在该包下创建一个用于文件上传的控制器类FileUploadController
package com.itheima.controller;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class FileUploadController {
@RequestMapping("fileUpload")
public String handleFormUpload(@RequestParam("name") String name,@RequestParam("uploadfile") List<MultipartFile> uploadfile,HttpServletRequest request){
if(!uploadfile.isEmpty()&&uploadfile.size()>0){
for(MultipartFile file: uploadfile){
String orginalFilename=file.getOriginalFilename();
String dirPath=request.getServletContext().getRealPath("/upload/");
File filePath=new File(dirPath);
if(!filePath.exists()){
filePath.mkdir();
}
String newFilename="_"+UUID.randomUUID()+"_"+orginalFilename;
try{
file.transferTo(new File(dirPath+newFilename));
}catch(Exception e){
e.printStackTrace();
return "error";
}
}
return "success";
}else{
return "error";
}
}
}
(7)将项目发布到tomcat上并启动
(8)上传文件
上传的文件在项目的发布路径中,而不是项目所在的目录。默认是在D:\Java_files.metadata.plugins\org.eclipse.wst.server.core\temp1\wtpwebapps\中
文件下载
文件下载就是将文件服务器中的问价下载到本机上,有两个步骤
(1)在客户端页面使用一个文件下载的超链接,该链接的href属性要指向后台文件下载的方法及方法名,示例:
<a href="${page.Context.request.contextPath}/download?filename=文件名">
文件下载
</a>
(2)在后台Controller类中,使用SpringMVC提供的文件下载方法进行文件下载,SpringMVC提供了一个ResponseEntity类型的对象。文件代码示例:
@RequestMapping("/download")
public ResponseEntity<byte[]>fileDownload(HttpServletRequest request,String filename)throws Exception{
//指定要下载文件的所在路径
String path=request.getServletContext().getRealPath("/upload");
//创建该文件对象
File file=new File(path+File.separator+filename);
//设置响应头
HttpHeaders headers=new HttpHeaders();
headers.setContentDispositionFormData("attachment", filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]> (FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
ResponseEntity对象用于直接返回结果对象。
示例:
(1)编写一个download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/download?filename=<%=URLEncoder.encode("壁纸.bmp","UTF-8") %>">
文件下载
</a>
</body>
</html>
在下载页面中对中文文件名编码。可以使用Servlet API中提供的URLEncoder类中的encoder(String s,String enc)方法将中文转为UTF-8编码
(2)在FileUploadController中编写fileDownload方法
@RequestMapping("/download")
public ResponseEntity<byte[]>fileDownload(HttpServletRequest request,String filename)throws Exception{
//指定要下载文件的所在路径
String path=request.getServletContext().getRealPath("/upload");
//创建该文件对象
File file=new File(path+File.separator+filename);
filename=this.getFilename(request,filename);
//设置响应头
HttpHeaders headers=new HttpHeaders();
headers.setContentDispositionFormData("attachment", filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]> (FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
public String getFilename(HttpServletRequest request,String filename)throws Exception{
String [] IEBrowserKeyWords={"MSIE","Trident","Edge"};
String userAgent=request.getHeader("User-Agent");
for(String keyWord:IEBrowserKeyWords){
if(userAgent.contains(keyWord)){
//IE内核浏览器,统一为UTF-8编码
return URLEncoder.encode(filename,"UTF-8");
}
}
//火狐等其他浏览器统一为ISO-8859-1编码
return new String(filename.getBytes("UTF-8"),"ISO-8859-1");
}
}
(3)重启tomcat访问地址http://localhost:9090/wenjian/downlod.jsp,注意下载的文件同样是在项目的发布路径中。