文件下载
- 文件上传: 将本机文件上传至服务器
- 文件下载: 将服务器上的文件下载至本地
如果是浏览器支持的文件格式,则下载后直接显示 ,例如 *.html , *.jpg 。如果浏览器不支持显示该文件,则提示保存到本地 ,例如 *.exe *.rar
注意:都是文件下载,区别是有的能直接显示。
Web Application 目录下的文件是由 tomcat 自动支持下载的。 但是:
- WEB-INF 和 META-INF 下的文件不支持下载
- Web Application 目录之外的文件不支持下载
文件下载的本质:tomcat把一个文件的内容传递给客户端。
自定义下载
自定义下载:使用 Servlet 自己控制下载
- 特点:
文件可以在任意位置(Web目录之外) ;
可以控制权限 可以控制下载速度 (下载限速) ;
可以控制是否允许多点下载(多线程下载) ;
其他方面的下载控制。
- 一个例子
所有用户的在头像存储在 d:\data\photo\ 下, 头像的命名规则: 20180001.jpg ,要求在 web 项目中显示加载显示头像。
实现步骤:
1 添加一个 Servlet : DownloadService
2 配置映射路径 /download/*
3 从访问URI里取得用户的请求参数, 对应到实际的本地文件
4 读取本地文件的内容,发送给客户端
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/download/*")
public class DownloadService extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//request.getRequestURI() /demo/download/20210001.jpg
String reqUri=request.getRequestURI();
int p1=reqUri.lastIndexOf('/');
int p2=reqUri.lastIndexOf('.');
String photoId=reqUri.substring(p1+1, p2);
//System.out.println(photoId);
File homeDie=new File("d:/test");
File targetFile=new File(homeDie, "/photo/"+photoId+".jpg");
//检查文件是否存在
if(!targetFile.exists() || !targetFile.isFile())
{
response.sendError(404,"该文件不存在!");
return;
}
// 应答:设置 Content-Type 和 Content-Length
String contentType="image/jpeg";
long contentLength=targetFile.length();
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(contentLength));
//读取目标文件,发送给客户端
InputStream inputstream=new FileInputStream(targetFile);
OutputStream outputStream=response.getOutputStream();
try
{
streamCopy(inputstream, outputStream);
} catch (Exception e)
{
try{inputstream.close();}catch (Exception e2) {}
}
outputStream.close();
}
private long streamCopy(InputStream in,OutputStream out) throws Exception
{
long count=0;
byte[] buf=new byte[8192];
while(true)
{
int n=in.read(buf);
if(n<0)
break;
if(n==0)
continue;
out.write(buf, 0, n);
count+=n;
}
return count;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
浏览器访问:http://127.0.0.1:8080/demo/download/20210001.jpg
前端无法区分这是一个Servlet还是一个静态文件 ,如 <img src="download/photo/20180001.jpg" />
内容类型 Content-Type
在 HTTP 应答的头部,需要指定内容的类型
示例:
HTTP/1.1 200
Content-Type: image/jpeg
Content-Length: 51967
- 内容类型主要分为5大类: text/* 、image/* 、audio/* 、video/* 、application/*
在HTTP应答时,应设置正确的 Content-Type, 浏览器会结合文件后缀和Content-Type来处理.
HTTP 404 错误
404 Not Found 是一个网站开发里常见的错误。
- HTTP 状态码 (HTTP Status Code) 分为四类:
2XX : 成功、正常、已受理
3XX : 重定向
4XX : 请求错误
5XX : 服务器错误
在 Servlet 里,可以调用 sendError() 返回应答错误:
//检查文件是否存在
if(!targetFile.exists() || !targetFile.isFile())
{
response.sendError(404,"该文件不存在!"+targetFile);
return;
}