1、概念
代表整个web项目,可以和web项目的容器(服务器)通信;
2、功能
①获取MIME类型;
②域对象:共享数据;
③获取文件的真实(服务器)路径
3、获取ServletContext对象
①通过request获取:
req.getServletContext();
②通过HttpServlet获取:
getServletContext();
因为MyServlet extends HttpServlet
备注:两种方式获取的是同一个ServletContext对象
4、ServletContext获取MIME类型
MIME类型:
在互联网通信过程中定义的一种文件数据类型;
格式:
大类型/小类型 比如:text/html、image/jpeg
5、域对象
方法:
1、void setAttribute(String name, Object value);
2、Object getAttribute(String name);
3、void removeAttribute(String name);
ServletContext对象范围:
所有用户所有请求的数据;
备注:使用的时候很谨慎!
6、获取文件的真实(服务器)路径
String getRealPath(String path);
读取文件代码示例:
package com.zibo.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet……");
System.out.println("转到doPost……");
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost……");
ServletContext servletContext = req.getServletContext();
//b.txt
String realPath_b = servletContext.getRealPath("/b.txt");
System.out.println(realPath_b);
//D:\MyFiles\IdeaProjects\web\out\artifacts\web_war_exploded\b.txt
File file_b = new File(realPath_b);
FileInputStream fileInputStream_b = new FileInputStream(file_b);
byte[] bytes_b = fileInputStream_b.readAllBytes();
System.out.println("b.txt读取到内容:"+new String(bytes_b));
//c.txt
String realPath_c = servletContext.getRealPath("/WEB-INF/c.txt");
System.out.println(realPath_c);
//D:\MyFiles\IdeaProjects\web\out\artifacts\web_war_exploded\WEB-INF\c.txt
File file_c = new File(realPath_c);
FileInputStream fileInputStream_c = new FileInputStream(file_c);
byte[] bytes_c = fileInputStream_c.readAllBytes();
System.out.println("c.txt读取到内容:"+new String(bytes_c));
//a.txt
String realPath_a = servletContext.getRealPath("/WEB-INF/classes/a.txt");
System.out.println(realPath_a);
//D:\MyFiles\IdeaProjects\web\out\artifacts\web_war_exploded\WEB-INF\classes\a.txt
File file_a = new File(realPath_a);
FileInputStream fileInputStream_a = new FileInputStream(file_a);
byte[] bytes_a = fileInputStream_a.readAllBytes();
System.out.println("a.txt读取到内容:"+new String(bytes_a));
}
}
运行结果:
文件位置备注:
二、文件下载
1、说明
如果超链接指向的资源可以被浏览器解析,则会展示在浏览器里面,否则弹出下载框,询问下载;
2、通过响应头设置资源的打开方式
conten-disposition:attachment;filename=xxx
3、步骤
第一步:定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename;
第二步:定义Servlet
第一步:获取文件名称;
第二步:使用字节输入流,加载文件进内存;
第三步:指定response的响应头:content-disposition:attachment;filename=xxx;
第四步:将数据写到response输出流;
4、代码演示
html文件代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/my?filename=1.jpg">下载图片</a>
</body>
</html>
服务器代码:
package com.zibo.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet……");
System.out.println("转到doPost……");
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost……");
ServletContext servletContext = req.getServletContext();
//1、获取文件名称——取参数
String filename = req.getParameter("filename");
//2、使用字节输入流,加载文件进内存——将文件读取到内存
//1.jpg
String realPath = servletContext.getRealPath("/img/"+filename);
File file = new File(realPath);
FileInputStream fileInputStream = new FileInputStream(file);
//3、指定response的响应头:content-disposition:attachment;filename=xxx
//设置响应头类型
String mimeType = servletContext.getMimeType(filename);
resp.setHeader("content-type",mimeType);
//设置响应头打开方式
resp.setHeader("content-disposition","attachment;filename="+filename);
//4、将输入流中的数据写到输出流中
ServletOutputStream stream = resp.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = fileInputStream.read(bytes))!=-1){
stream.write(bytes,0,len);
}
fileInputStream.close();
}
}
运行结果:
文件位置备注:
5、中文文件名乱码问题
DownloadUtils:
package com.zibo.servlet.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DownloadUtils {
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, StandardCharsets.UTF_8);
filename = filename.replace("+", " ");
}else {
// 其它浏览器
filename = URLEncoder.encode(filename, StandardCharsets.UTF_8);
}
return filename;
}
}
改造后的服务器代码:
package com.zibo.servlet;
import com.zibo.servlet.utils.DownloadUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet……");
System.out.println("转到doPost……");
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost……");
ServletContext servletContext = req.getServletContext();
//1、获取文件名称——取参数
String filename = req.getParameter("filename");
//2、使用字节输入流,加载文件进内存——将文件读取到内存
//1.jpg
String realPath = servletContext.getRealPath("/img/"+filename);
File file = new File(realPath);
FileInputStream fileInputStream = new FileInputStream(file);
//3、指定response的响应头:content-disposition:attachment;filename=xxx
//设置响应头类型
String mimeType = servletContext.getMimeType(filename);
resp.setHeader("content-type",mimeType);
//设置响应头打开方式
//解决中文乱码问题
//1、获取user-agent请求头
String header = req.getHeader("user-agent");
//2、使用工具类方法编码文件名
filename = DownloadUtils.getFileName(header, filename);
resp.setHeader("content-disposition","attachment;filename="+filename);
//4、将输入流中的数据写到输出流中
ServletOutputStream stream = resp.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = fileInputStream.read(bytes))!=-1){
stream.write(bytes,0,len);
}
fileInputStream.close();
}
}
运行结果: