创建时间:6.19 & 6.24

1.案例-完成文件下载

1)  什么情况下会文件下载?

浏览器不能解析的文件就下载

*使用a标签直接指向服务器上的资源

2)什么情况下需要在服务端编写文件下载的代码?

理论上,浏览器可以解析的代码需要编写文件下载代码

实际开发中,只要是下载的文件都编写文件下载代码

文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需要IO技术将服务器端的文件使用InputStream读取到,在使用      ServletOutputStream写到response缓冲区中

代码如下:

上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上,而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式。

1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);

2)告示浏览器文件的打开方式是下载:

response.setHeader("Content-Disposition","attachment;filename=文件名称");

代码如下:

*客户端不是根据文件扩展名来区分文件的类型,而是通过文件的MIME类型(在tomcat的web.xml中对extension进行MIME的映射)

但是,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,  原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容   性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一个属性可以辨别

解决乱码方法如下(不要记忆--了解):

其中agent就是请求头User-Agent的值

 if (agent.contains("MSIE")) {

             // IE浏览器

             filename = URLEncoder.encode(filename, "utf-8");

             filename = filename.replace("+", " ");

 } else if (agent.contains("Firefox")) {

             // 火狐浏览器

 BASE64Encoder base64Encoder = new BASE64Encoder();

             filename = "=?utf-8?B?"

                       + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

 } else {

             // 其它浏览器

             filename = URLEncoder.encode(filename, "utf-8");                    

 }

完整代码:见WEB14代码DownloadServlet2.java

 package com.itheima.content;

 import java.io.FileInputStream;

 import java.io.IOException;

 import java.io.InputStream;

 import java.net.URLEncoder;

 import javax.servlet.ServletException;

 import javax.servlet.ServletOutputStream;

 import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 import sun.misc.BASE64Encoder;

 public class DownLoadServlet2 extends HttpServlet {

       protected void doGet(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

             //*******文件名称是中文的下载*******

             //获得要下载的文件的名称

             String filename = request.getParameter("filename");//????.jpg

             //解决获得中文参数的乱码----下节课讲

             filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg

             //获得请求头中的User-Agent

             String agent = request.getHeader("User-Agent");

             //根据不同浏览器进行不同的编码

             String filenameEncoder = "";

             if (agent.contains("MSIE")) {

                   // IE浏览器

                   filenameEncoder = URLEncoder.encode(filename, "utf-8");

                   filenameEncoder = filenameEncoder.replace("+", " ");

             } else if (agent.contains("Firefox")) {

                   // 火狐浏览器

                   BASE64Encoder base64Encoder = new BASE64Encoder();

                   filenameEncoder = "=?utf-8?B?"

                              + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

             } else {

                   // 其它浏览器

                   filenameEncoder = URLEncoder.encode(filename, "utf-8");                  

             }

             //要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型

             response.setContentType(this.getServletContext().getMimeType(filename));

             //告诉客户端该文件不是直接解析 而是以附件形式打开(下载)----filename="+filename 客户端默认对名字进行解码

             response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);

             //获取文件的绝对路径

             String path = this.getServletContext().getRealPath("download/"+filename);

             //获得该文件的输入流

             InputStream in = new FileInputStream(path);

             //获得输出流---通过response获得的输出流 用于向客户端写内容

             ServletOutputStream out = response.getOutputStream();

             //文件拷贝的模板代码

             int len = 0;

             byte[] buffer = new byte[1024];

             while((len=in.read(buffer))>0){

                   out.write(buffer, 0, len);

             }

             in.close();

             //out.close();

       }

       protected void doPost(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

             doGet(request, response);

       }

 }

response细节点:

1)response获得的流不需要手动关闭,web容器(tomcat)会帮助我们关闭

2)getWritergetOutputStream不能同时调用

验证码案例:不用掌握生成验证码,只要掌握html页面里怎么改

[转]【HttpServlet】HttpServletResponse接口 案例:完成文件下载的更多相关文章

  1. HttpServletRequest 接口、HttpServletResponse 接口、请求转发与重定向

    上篇文章我们讲了servlet的基本原理,这章将讲一下剩余的部分. HttpServletRequest 接口 该接口是 ServletRequest 接口的子接口,封装了 HTTP 请求的相关信息, ...

  2. Servlet(6)—HttpServletRequest接口和HttpServletResponse接口

    HttpServletRequest接口和HttpServletResponse接口是继承ServletRequest和ServletResponse接口,是他们的子接口,但是我们在程序中进程看到Se ...

  3. HttpServletRequest HttpServletResponse接口详解

    HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求 ...

  4. Yarn的Tool接口案例

    目录 Yarn的Tool接口案例 Tool接口环境准备 1 新建Maven项目YarnDemo 编写代码 打包jar上传到集群 Yarn的Tool接口案例 Tool接口环境准备 之前写wordcoun ...

  5. HttpServletResponse接口详解

    在 Servlet API 中,定义了一个 HttpServletResponse 接口,它继承自 ServletResponse 接口.HttpServletResponse 对象专门用来封装 HT ...

  6. HttpServletResponse接口

    public interface HttpServletResponse extends ServletResponse 描述一个返回到客户端的HTTP回应.这个接口允许Servlet程序员利用HTT ...

  7. Servlet--HttpServletRequest接口,HttpServletResponse接口

    HttpServletRequest接口 定义 public interface HttpServletRequest extends ServletRequest; 用来处理一个对 Servlet ...

  8. JavaWeb案例: 文件下载 基于tomcat8 默认编码为UTF-8

    package cn.itcast.download; import javax.servlet.ServletException; import javax.servlet.ServletOutpu ...

  9. [转]【response】HttpServletResponse接口

    创建时间:6.19 & 6.24 1.HttpServletResponse概述 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参 ...

随机推荐

  1. Day01 确定选题

    一起来选题 一.谁想个选题? 今天是第一节大软课,大家需要进行分组和确定选题.分组固然是快乐的,但是确定选题是让人费脑筋的.要新颖!要有需求!要我们能实现(笑)......大家面面相觑.面对这种情况, ...

  2. [NOI2019]回家路线(最短路,斜率优化)

    终于把这鬼玩意弄完了-- 为什么写的这么丑-- (顺便吐槽 routesea) 最短路的状态很显然:\(f[i]\) 表示从第 \(i\) 条线下来的最小代价. 首先明显要把那个式子拆开.直觉告诉我们 ...

  3. [LeetCode] 885. Spiral Matrix III 螺旋矩阵之三

    On a 2 dimensional grid with R rows and C columns, we start at (r0, c0) facing east. Here, the north ...

  4. Visual Studio 调试系列9 调试器提示和技巧

    系列目录     [已更新最新开发文章,点击查看详细] 01 固定数据提示 如果你在调试时,经常将鼠标悬停在数据提示上,就可能想固定变量的数据提示,方便自己随时查看. 即使在重新启动后,固定的变量也能 ...

  5. Golang(八)go modules 学习

    0. 前言 最近加入鹅厂学习 k8s,组内使用 Go 1.11 以上的 go modules 管理依赖,因此整理了相关资料 本文严重参考原文:初窥Go module 1. 传统 Golang 包依赖管 ...

  6. 图解微信小程序---添加tabBar底部菜单,添加已做好轮播图操作

    图解微信小程序---添加tabBar底部菜单,添加已做好轮播图操作 什么是tabBar? 顶部或者底部tab栏如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以 ...

  7. .net core vue+wangEditor (双向绑定) 上传图片和视频功能

    最终效果,是这样的,现在开始记录怎么做: 开始 npm 安装 wangEditor 安装好后, 因为要用vue 双向绑定 ,所以 我就把wangwangEditor 做成了一个封装组件,先看一下目录 ...

  8. halcon机器视觉工程开发思路

    参考:halcon学习笔记——机器视觉工程应用的开发思路https://www.cnblogs.com/hanzhaoxin/archive/2013/02/15/2912879.html

  9. PIE SDK主成分变换

    1.算法功能简介   主成分变换(Principal Component Analysis,PCA)又称K-L(Karhunen-Loeve)变换或霍特林(Hotelling)变换,是基于变量之间的相 ...

  10. 【C#】Winform 令人困擾的畫面閃爍問題解法

    DoubleBuffered = true 如果 Control 沒有這個屬性,可以使用我下列擴充函式進行設定︰ public static void SetDoubleBuffered<T&g ...