java Web ServletContext和下载文件案例
2020/8/20
1.ServletContext
视频笔记
代码实现3个功能,代码如下:
1.实现获取context的两种方法
package cn.zsc.web.servlet;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(name = "context1",urlPatterns = "/context1")
public class contextDemo1 extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//获取context对象有两种方法
//1.通过request对象来获取
ServletContext ct1 = request.getServletContext();
//2.通过HttpServlet获取
ServletContext ct2 = this.getServletContext();
System.out.println(ct1);
System.out.println(ct2);
System.out.println(ct1==ct2);
//因为ServletContext代表整个web应用,只有当前web应用,所以在用“==”去比较时输出的结果为true,两个context对象的哈希码值都一样
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
this.doPost(request,response);
}
}
2.实现第一个功能:获取MIME类型
package cn.zsc.web.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.IOException;
@WebServlet(name = "contextDemo2 ",urlPatterns = "/context2")
public class contextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext功能,获取MIME类型
//1.获取ServletContext对象
ServletContext context = this.getServletContext();
//2.定义文件的名称
String fire="1.jpg";
//3.通过ServletContext对象来获取MIME类型
String mimeType = context.getMimeType(fire);
//4.打印获取的MIME类型
System.out.println(mimeType);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
3.实现第二个功能:使用ServletContext对象来共享数据
(1)储存数据
package cn.zsc.web.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.IOException;
@WebServlet(name = "contextSetDemo1",urlPatterns = "/context3")
public class contextSetDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用ServletContext对象来共享数据
//1.获取context对象
ServletContext context = this.getServletContext();
//2.使用setAttribute方法来存储数据
context.setAttribute("name","zsc");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
(2)读取数据
package cn.zsc.web.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.IOException;
@WebServlet(name = "contextGetDemo2",urlPatterns = "/context4")
public class contextGetDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过context对象的getAttribute方法来获取共享数据
//1.获取ServletContext对象
ServletContext cotext = this.getServletContext();
//2.获取共享数据
Object name = cotext.getAttribute("name");
System.out.println(name);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
3.实现第三个功能:通过ServletContext对象的getRealPath()来获取文件的服务器路径(真实路径)
package cn.zsc.web.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.IOException;
@WebServlet(name = "contextDemo3",urlPatterns = "/context5")
public class contextDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过ServletContext对象的getRealPath()来获取文件的服务器路径(真实路径)
//获取context
ServletContext context = this.getServletContext();
//获取文件的服务器路径(文件在web目录下),只需要在文件名前面加斜杠
String realPath = context.getRealPath("/zsc1.txt");
//打印一下路径
System.out.println(realPath);
//获取文件的服务器路径(文件在WEB-INF目录下),只需要在文件名前面加/WEB-INF/这样的路径
String realPath1 = context.getRealPath("/WEB-INF/zsc.txt");
//打印一下路径
System.out.println(realPath1);
//获取文件的服务器路径(文件在src目录下),只需要在文件名前面加/WEB-INF/classes/这样的路径
String realPath2 = context.getRealPath("/WEB-INF/classes/zsc2.txt");
//打印一下路径
System.out.println(realPath2);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
注意这里会有一个填写路劲问题有三种情况
1.获取文件的服务器路径(文件在web目录下),只需要在文件名前面加斜杠
2.获取文件的服务器路径(文件在WEB-INF目录下),只需要在文件名前面加/WEB-INF/这样的路径
3.获取文件的服务器路径(文件在src目录下),只需要在文件名前面加/WEB-INF/classes/这样的路径
2.下载文件的案例
需求,分析和步骤
附上视频截图
代码如下
package cn.zsc.servlect;
import cn.zsc.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.FileInputStream;
import java.io.IOException;
/***
* 完成文件下载操作,并且每次单击超链接都会弹出对话框
* 步骤
* 1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
* 2. 定义Servlet
* 1. 获取文件名称
* 2. 使用字节输入流加载文件进内存
* 3. 指定response的响应头: content-disposition:attachment;filename=xxx和content-type
* 4. 将数据写出到response输出流
*/
@WebServlet(name = "DownloadServlet",urlPatterns = "/Download")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取文件名称(获取请求参数)
String filename = request.getParameter("name");
//2.使用字节输入流加载文件进内存(在写进内存之前要获取该文件的真实路径)
//获取文件真实路径
ServletContext context = this.getServletContext();
String realPath = context.getRealPath("/image/"+filename); //文件在web目录下直接写斜杠
//使用字节流
FileInputStream in=new FileInputStream(realPath);
//3.设置响应头(content-disposition和content-type),为了单击超链接会弹出对话框
//设置content-type的值,所以要先获取当前文件的MIME
String mimeType = context.getMimeType(filename);
response.setHeader("content-type",mimeType);
//注意在这里要先解决如果文件为中文时会出现的问题
//1.获取user-agent请求头
String agent = request.getHeader("user-agent");
//2.使用工具类的静态方法,并且重新赋值给filename
filename = DownLoadUtils.getFileName(agent, filename);
//设置content-disposition
response.setHeader("content-disposition","attachment;filename="+filename);
//4.将数据写出到response输出流
//获取输出流
ServletOutputStream out = response.getOutputStream();
//读取输入流数据,并且写入输出流
byte[] b=new byte[102400*8];
if (in.read(b)!=-1){
out.write(b,0,b.length);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
在这里会遇到一个问题,中文文件名的问题,可以使用下面的工具类来解决。
使用工具类的静态方法时要先获取请求头“user-agent”的值,然后使用该工具类
代码如下
package cn.zsc.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class DownLoadUtils {
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}