servletContext&Requset&Response

ServletContext&Requset&Response

第一章 ServletContext对象

1.1 什么是ServletContext

ServletContext:Servlet的上下文对象。ServletContext对象对Servlet之前和之后的内容都知道。这个对象一个web项目只有一个。在服务器启动的时候为每个web项目创建一个单独的ServletContext对象。

1.2 ServletContext对象的作用

1.2.1 用来获取web项目信息

因为一个web项目只有一个ServletContext对象,所以这个对象对整个项目的相关内容都是了解的。

方法 返回值 描述
getMimeType(String file) String 获取文件的MIME类型
getContextPath() String 获取web项目请求工程名
getInitParameter(String name) String 获取web项目的初始化参数
getInitParameterNames() Enumeration 获取web项目的初始化参数

演示:

  • web.xml
<!-- 全局初始化参数的配置 -->
<context-param>
    <param-name>username</param-name>
    <param-value>root</param-value>
</context-param>
<context-param>
    <param-name>password</param-name>
    <param-value>123</param-value>
</context-param>
  • servlet
/**
 * ServletContext对象作用一:获取web项目的信息
 */
public class ServletDemo5 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1.获取文件的MIME的类型:
		// 获得ServletContext
		ServletContext servletContext = this.getServletContext();
		String mimeType = servletContext.getMimeType("aa.txt");
		System.out.println(mimeType);
		// 2.获得请求路径的工程名:
		String path = servletContext.getContextPath();
		System.out.println(path);
		// 3.获得全局初始化参数:
		String username = servletContext.getInitParameter("username");
		String password = servletContext.getInitParameter("password");
		System.out.println(username+"    "+password);
		Enumeration<String> names = servletContext.getInitParameterNames();
		while(names.hasMoreElements()){
			String name = names.nextElement();
			String value = servletContext.getInitParameter(name);
			System.out.println(name+"    "+value);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

1.2.2 读取web项目下的文件

之前使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat下才能访问的。获取web项目下的文件如果使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境)。

方法 返回值 描述
getResourceAsStream(String path) InputStream 读取指定文件到流中
getRealPath(String path) String 返回一个指定虚拟路径文件 的真实路径(完整路径)的字符串

演示

  • db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web02
username=root
password=abc
  • servlet
/**
 * web项目中的读取文件
 */
public class ServletDemo6 extends HttpServlet {
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//test1();
		test2();
	}
	/**
	 * 读取web项目下的文件:使用ServletContext读取
	 * getRealPath(String path)方式
	 */
	private void test2() throws IOException{
		// 使用ServletContext方式:
		Properties properties = new Properties();
		// 创建一个文件的输入流:
		// InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
		String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
		System.out.println(path);
		InputStream is = new FileInputStream(path);
		properties.load(is);
		// 获取数据:
		String driverClassName = properties.getProperty("driverClassName");
		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		// 输出到控制台
		System.out.println(driverClassName);
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}	
    
	/**
	 * 读取web项目下的文件:使用ServletContext读取
	 * getResourceAsStream(String path)方式
	 */
	private void test1() throws IOException{
		// 使用ServletContext方式:
		Properties properties = new Properties();
		// 创建一个文件的输入流:
		// InputStream is = new FileInputStream("classes/db.properties");
		InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
		properties.load(is);
		// 获取数据:
		String driverClassName = properties.getProperty("driverClassName");
		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		// 输出到控制台
		System.out.println(driverClassName);
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

1.2.3 作为域对象存取数据

什么是域对象

域对象:指的是将数据存入到域对象中,这个数据就会有一定的作用范围。域指的是一定的作用范围。

ServletContext作为域对象

ServletContext是在服务器启动的时候为每个web项目单独创建一个ServletContext对象。当web项目从服务器中移除,或者是关闭服务器的时候ServletContext对象会被销毁。向ServletContext中保存的数据一直存在(当服务器关闭的时候ServletContext对象被销毁,然后里面数据才会失效)。

  • ServletContext作用范围:整个web应用。
方法 返回值 描述
setAttribute(String name, Object obj) void 存入数据的方法
getAttribute(String name) Object 获取数据的方法
removeAttribute(String name) void 移除数据的方法

演示 ServletContext作为域对象的作用范围。先访问ServletDemo7,再访问ServletDemo8。

  • servlet
/**
 * ServletContext的域对象的演示
 */
public class ServletDemo7 extends HttpServlet {

	@Override
	public void init() throws ServletException {
		// 当ServletDemo7被创建,初始化一个值。
		this.getServletContext().setAttribute("name", "张三");
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String) this.getServletContext().getAttribute("name");
		System.out.println("姓名:"+name);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		doGet(request, response);
	}

}
/**
 * ServletContext的域对象的演示
 */
public class ServletDemo8 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String) this.getServletContext().getAttribute("name");
		System.out.println("姓名:"+name);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doGet(request, response);
	}

}

第二章 Response对象

2.1 Response概述

什么是Response

开发的软件是B/S结构的软件,可以通过浏览器访问服务器的软件。

  • 从浏览器输入一个地址访问服务器(将这个过程称为是请求)。
  • 服务器接收到请求,需要进行处理,处理以后需要将处理结果显示回浏览器端(将这个过程称为是响应Response)。

2.2 Response对象的API

关于响应行的方法

方法 返回值 描述
setStatus(int sc) void 设置响应的状态码
  • 设置响应的状态码
    • 200 正确
    • 302 重定向
    • 304 查找本地缓存
    • 404 请求资源部存在
    • 500 服务器内部错误

演示

/**
 * 设置响应的状态码
 */
public class ResponseDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应的状态码:
        response.setStatus(404);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

关于响应头的方法

方法 返回值 描述
setDateHeader(String name, long date) void 设置响应头
setHeader(String name, String value) void 设置响应头
setIntHeader(String name, int value) void 设置响应头
  • set开头的方法:针对一个key对应一个value的情况。

    • 举例:比如已有一个响应头 content-Type:text/html ,然后执行 setHeader(“content-Type”,”text/plain”);
    • 最终得到响应头的结果:content-Type:text/plain
方法 返回值 描述
setDateHeader(String name, long date) void 设置响应头
setHeader(String name, String value) void 设置响应头
setIntHeader(String name, int value) void 设置响应头
  • add开头的方法:针对一个key对应多个value的情况。
    • 举例:比如已有一个响应头content-Type:text/html ,然后执行addHeader(“content-Type”,”text/plain”);
    • 最终得到响应头的结果:content-Type:text/html,text/plain

演示

/**
 * 使用状态码和Location头完成重定向
 */
public class ResponseDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 完成重定向
        response.setStatus(302);
        // 设置响应头
        response.setHeader("Location", "/web01/ResponseDemo2");
        
        //实际开发中可以使用下面的代码,替换重定向两句写法
        //response.sendRedirect("/web01/ResponseDemo2");

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

关于响应体的方法

方法 返回值 描述
getOutputStream() ServletOutputStream 返回一个字节流,用于向浏览器发送数据
getWriter() PrintWriter 放回一个字符流,用于向浏览器发送数据

与 其他API 一起演示了

其他常用的API

方法 放回值 描述
sendRedirect(String location) void 重定向方法
setContextType(String type) void 设置浏览器打分页面时采用的字符集
setCharacterEncoding(String charset) void 设置响应字符流的缓冲区字符集

演示

/**
 * 定时刷新
 */
public class ResponseDemo1 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
		// 定时刷新
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().println("5秒以后页面跳转!");
		response.setHeader("Refresh", "5;url=/web01/ResponseDemo2");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
/**
 * 重定向后的页面
 */
public class ResponseDemo2 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("ResponseDemo2...");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

2.3 Response对象响应中文乱码处理

提问:在Servlet中编写以下代码,向页面输出中文是否会产生乱码?

response.getWriter().println("中文");

会乱码:

  • 原因:

  • 字符流是有缓冲区的,response获得字符流,response设计默认的缓冲区编码是ISO-8859-1。这个字符集不支持中文的。

  • 解决:

    • 设置response获得字符流缓冲区的编码和设置浏览器默认打开时候采用的字符集一致即可。

使用字节流响应中文

/**
 * Response响应中文的处理
 */
public class ResponseDemo3 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        test1(response);
    }

    /**
	 * 使用字节流输出中文
	 */
    private void test1(HttpServletResponse response) throws IOException, UnsupportedEncodingException {
        // 使用字节流的方式输出中文:
        ServletOutputStream outputStream = response.getOutputStream();
        // 设置浏览器默认打开的时候采用的字符集
        response.setHeader("Content-Type", "text/html;charset=UTF-8");
        // 设置中文转成字节数组字符集编码
        outputStream.write("中文".getBytes("UTF-8"));
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

使用字符流响应中文

/**
 * Response响应中文的处理
 */
public class ResponseDemo3 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        test2(response);
    }
    /**
	 * 使用字符流输出中文
	 */
    private void test2(HttpServletResponse response) throws IOException, UnsupportedEncodingException {
        // 设置浏览器默认打开的时候采用的字符集:
        // response.setHeader("Content-Type", "text/html;charset=UTF-8");
        // 设置response获得字符流的缓冲区的编码:
        // response.setCharacterEncoding("UTF-8");
        // 简化代码
        response.setContentType("text/html;charset=UTF-8");
        // 会不会产生乱码
        response.getWriter().println("中文");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

第三章 Request

3.1 Request概述

什么是Request

开发的软件都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request对象)。

3.2 Request对象的API

获得客户端信息

方法 返回值 描述
getMethod() String 获取请求的方法
getQueryString() String 获取请求路径后的提交参数的字符串
getRequestURI() String 获取请求路径的URI
getRequestURL() StringBuffer 获取请求路径的URL
getRemoteAddr() String 获取客户端的IP地址

演示

/**
 * Request对象获得客户机信息
 */
public class RequestDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获得请求方式:
		System.out.println("请求方式:"+request.getMethod());
		// 获得客户机的IP地址:
		System.out.println("客户机IP地址:"+request.getRemoteAddr());
		// 获得请求参数的字符串
		System.out.println("请求参数的字符串:"+request.getQueryString());
		// 获得请求路径的URL和URI
		System.out.println("请求路径的URL:"+request.getRequestURL());
		System.out.println("请求路径的URI:"+request.getRequestURI());
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

获得请求头的方法

方法 返回值 描述
getHeader(String name) String 获得一个key对应一个value的请求头
getHeaders(String name) Enumeration 获得一个key对应多个value的请求头

演示

/**
 * Request对象获得请求头的方法
 */
public class RequestDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获得请求头的信息
		System.out.println("获得客户机浏览器类型:"+request.getHeader("User-Agent"));
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

获得请求参数的方法

方法 返回值 描述
getParameter(String name) String 获得提交的参数(一个name对应一个value)
getParameterValues(String name) String[] 获得提交的参数(一个name对应多个value)
getParameterMap() Map 获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中

演示

  • 静态页面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>request接收表单参数</h1>
        <form action="/web01/RequestDemo2" method="post">
            用户名:<input type="text" name="username"/><br/>
            密码:<input type="password" name="password"><br/>
            性别:<input type="radio" name="sex" value="man"/>男<input type="radio" name="sex" value="woman"/>女<br/>
            籍贯:<select name="city">
            <option value="beijing">北京市</option>
            <option value="shanghai">上海市</option>
            <option value="shenzhen">深圳市</option>
            </select><br/>
            爱好:<input type="checkbox" name="hobby" value="basketball"/>篮球
            <input type="checkbox" name="hobby" value="football"/>足球
            <input type="checkbox" name="hobby" value="volleyball"/>排球<br/>
            自我介绍:<textarea name="info" rows="3" cols="8"></textarea><br/>
            <input type="submit" value="提交">
        </form> 
    </body>
</html>
  • servlet
/**
 * Request接收表单参数
 */
public class RequestDemo2 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 接收用户名和密码:
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 接收性别和籍贯:
		String sex = request.getParameter("sex");
		String city = request.getParameter("city");
		// 接收爱好:
		String[] hobby = request.getParameterValues("hobby");
		// 接收自我介绍
		String info = request.getParameter("info");
		System.out.println("用户名:"+username);
		System.out.println("密码:"+password);
		System.out.println("性别:"+sex);
		System.out.println("籍贯:"+city);
		System.out.println("爱好:"+Arrays.toString(hobby));
		System.out.println("自我介绍:"+info);
		
		// 使用getParameterMap接收数据:
		Map<String, String[]> map = request.getParameterMap();
		for (String key:map.keySet()) {
			String[] value = map.get(key);
			System.out.println(key+"    "+Arrays.toString(value));
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

3.3 Request对象接收表单请求参数的中文乱码处理

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>request接收中文数据</h1>
        <h3>POST方式接收中文</h3>
        <form action="/web01/RequestDemo3" method="post">
            姓名:<input type="text" name="name"/><br/>
            <input type="submit" value="提交">
        </form>

        <h3>GET方式接收中文</h3>
        <form action="/web01/RequestDemo3" method="get">
            姓名:<input type="text" name="name"/><br/>
            <input type="submit" value="提交">
        </form>
    </body>
</html>

POST方式接收中文

  • 产生乱码的原因:
    • post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区就有编码(默认ISO-8859-1:不支持中文).
  • 解决方案:
    • 将request的缓冲区的编码修改了即可。
/**
 * 演示post方式处理中文乱码
 */
public class RequestDemo3 extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置缓冲区的编码
        request.setCharacterEncoding("UTF-8");
        //接收数据
        String name = request.getParameter("name");
        System.out.println("姓名:"+name);
    }
}

GET方式接收中文

  • 产生乱码原因:
    • get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了。
  • 解决方案:
    • 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
public class RequestDemo3 extends HttpServlet {
    /**
	 * 演示get方式处理中文乱码
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接收数据:
        // request.setCharacterEncoding("UTF-8");
       
        String name = request.getParameter("name");
        /*
        String encode = URLEncoder.encode(name, "ISO-8859-1");
		String decode = URLDecoder.decode(encode, "UTF-8");
		System.out.println("姓名:"+decode);
		*/
      
      	//在tomcat8之后,get方式的请求已经支持中文,所以不用再手动的这是编码.
        String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");
        System.out.println("姓名:"+value);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
    }

}

第四章 综合案例

4.1 案例 记录网站的登录成功的人数.

案例需求:

登录成功后,5秒后跳转到某个页面,在页面中显示您是第x位登录成功的用户.

案例分析:

代码实现:

  • 页面代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <form action="./userServlet" method="post">
            用户名:<input type="text" name="username" value="jack" /> <br/>
            密码:<input type="text" name="password" value="123456" /> <br/>
            <input type="submit" value="提交" />
        </form>

    </body>
</html>
  • servlet
/**
 * 登录代码的Servlet
 */
public class UserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void init() throws ServletException {
        // 初始化一个变量count的值为0.
        int count = 0;
        // 将这个值存入到ServletContext中.
        this.getServletContext().setAttribute("count", count);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            response.setContentType("text/html;charset=UTF-8");
            // 1.接收表单提交的参数.
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            // 2.封装到实体对象中.
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);

            // 3.调用业务层处理数据.
            UserService userService = new UserService();

            User existUser = userService.login(user);
            // 4.根据处理结果显示信息(页面跳转).
            if(existUser == null){
                // 登录失败
                response.getWriter().println("<h1>登录失败:用户名或密码错误!</h1>");
            }else{
                // 登录成功

                // 记录次数:
                int count = (int) this.getServletContext().getAttribute("count");
                count++;
                this.getServletContext().setAttribute("count", count);

                response.getWriter().println("<h1>登录成功:您好:"+existUser.getUsername()+"</h1>");
                response.getWriter().println("<h3>页面将在5秒后跳转!</h3>");
                response.setHeader("Refresh", "5;url=/day02/countServlet");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
/**
 * 显示登入次数的Servlet
 */
public class CountServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获得Count的值。
        response.setContentType("text/html;charset=UTF-8");
        int count = (int) this.getServletContext().getAttribute("count");
        response.getWriter().println("<h1>您是第"+count+"位登录成功的用户!</h1>");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

4.2 案例 完成文件下载

案例需求:

点击列表中的某些链接,下载文件

页面资源 存的web下的download目录下

案例分析:

实现文件下载功能比较简单,通常情况下,不需要使用第三方组件实现,而是直接使用Servlet类和输入/输出流实现。与访问服务器文件不同的是,要实现文件的下载,不仅需要指定文件的路径,还需要在HTTP协议中设置两个响应消息头,具体如下:

//设定接收程序处理数据的方式
Content-Disposition: attachment; filename =

//设定实体内容的MIME类型
Content-Type:application/x-msdownload
  1. 浏览器会直接处理响应的内容,需要在HTTP响应消息中设置两个响应消息头字段,用来指定接收程序处理数据内容的方式为下载方式。

  2. 当单击“下载”超链接时,系统将请求提交到对应的Servlet。

  3. 在该Servlet中,首先获取下载文件的地址,并根据该地址创建文件字节输入流,然后通过该流读取下载文件内容,最后将读取的内容通过输出流写到目标文件中。

代码实现:

页面代码:

<h1>直接通过url地址访问静态资源</h1>
<a href="/day02/download/a.flv">a.flv</a><br/>
<a href="/day02/download/a.jpg">a.jpg</a><br/>
<a href="/day02/download/a.mp3">a.mp3</a><br/>
<a href="/day02/download/a.mp4">a.mp4</a><br/>
<a href="/day02/download/a.txt">a.txt</a><br/>
<a href="/day02/download/a.zip">a.zip</a><br/>

<h1>[名称中含有中文]直接通过url地址访问静态资源</h1>
<a href="/day02/download?filename=a.jpg">下载a.jpg</a><br/>
<a href="/day02/download?filename=美女.jpg">下载美女.jpg</a><br/>

servlet代码:

  • Firefox浏览器下载中文文件的时候采用的是Base64的编码.

  • IE浏览器,谷歌浏览器等,下载中文文件的时候采用的URL的编码.

有关编码问题,可以使用工具类“DownloadUtils.java”进行处理

/**
 * 文件下载的Servlet
 */
@WebServlet(name = "DownloadServlet",urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收参数
        String filename = new String(request.getParameter("filename"));
        System.out.println(filename);
        // 2.完成文件下载:
        // 2.1设置Content-Type头
        String type = this.getServletContext().getMimeType(filename);
        response.setHeader("Content-Type", type);
        // 2.3设置文件的InputStream.
        String realPath = this.getServletContext().getRealPath("/download/" + filename);

        // 根据浏览器的类型处理中文文件的乱码问题:
        String agent = request.getHeader("User-Agent");
        System.out.println(agent);
        if (agent.contains("Firefox")) {
            filename = base64EncodeFileName(filename);
        } else {
            filename = URLEncoder.encode(filename, "UTF-8");
        }

        // 2.2设置Content-Disposition头
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);

        InputStream is = new FileInputStream(realPath);
        // 获得response的输出流:
        OutputStream os = response.getOutputStream();
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = is.read(b)) != -1) {
            os.write(b, 0, len);
        }
        is.close();
    }

    public static String base64EncodeFileName(String fileName) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        try {
            return "=?UTF-8?B?"
                    + new String(base64Encoder.encode(fileName
                    .getBytes("UTF-8"))) + "?=";
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

上一篇:session的使用


下一篇:ServletContext对象