一、ServletContext对象

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));
    }
}

运行结果:

E015Web学习笔记-Request和Respons(三)_响应头

文件位置备注:

E015Web学习笔记-Request和Respons(三)_响应头_02

 

二、文件下载

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();
    }
}

运行结果:

E015Web学习笔记-Request和Respons(三)_Request和Respons_03

文件位置备注:

E015Web学习笔记-Request和Respons(三)_Request和Respons_04

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();
    }
}

运行结果:

E015Web学习笔记-Request和Respons(三)_java_05