创建时间: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. ACE网络编程:IPC SAP、ACE_SOCKET和TCP/IP通信实例

    socket.TLI.STREAM管道和FIFO为访问局部和全局IPC机制提供广泛的接口.但是,有许多问题与这些不统一的接口有关联.比如类型安全的缺乏和多维度的复杂性会导致成问题的和易错的编程.ACE ...

  2. ZROI 暑期高端峰会2019 总结

    FBI Warning:以下博客含有 FBI Warning 的都是包含大量人类本质之一的. 前几天听课: Day1 组合计数 Day1 序列数据结构 Day2 线性代数 Day3 图论 Day3 字 ...

  3. divide two numbers using + opertor

    package testpacknm; import java.util.Scanner; public class testcnm { public static void main(String[ ...

  4. Salesforce 开发整理(十一) 自定义放大镜查找效果

    有时候在自定义的visualforce页面上,需要实现系统标准的查找样式,当不能使用标准的style的时候,我们只能选择自定义实现,下面分享一个demo,预览效果如下: 实现代码,Visualforc ...

  5. 万亿数据下Hadoop的核心竞争力

    1.前言 在大数据时代,Hadoop有着得天独厚的优势.然而,每个企业的技术储备和需求特点不同,他们希望从海量的客户数据中挖掘真正的商业价值,像Google.Facebook.Twitter等这样的企 ...

  6. mybatis 的 dao 接口跟 xml 文件里面的 sql 是如何建立关系的?

    mybatis 会先解析这些xml 文件,通过 xml 文件里面的命名空间 (namespace)跟dao 建立关系:然后 xml 中的每段 sql 会有一个id 跟 dao 中的接口进行关联. 那么 ...

  7. Shell脚本——求随机数的最值

    写一个脚本,利用RANDOM生成10个随机数,并找出其中的最大值,和最小值: #!/bin/bash # MAX= MIN= ..};do RAN=$RANDOM [ $i -eq ] &&a ...

  8. HTML--元素居中各种处理方法2

    紧接上一篇. 如果要居中的是一个块元素呢. 1)如果你知道这个块元素的高度: <main> <div> I'm a block-level element with a fix ...

  9. 常见HTTP响应状态码

    分类 分类 分类描述 1** 信息,服务器收到请求,需要请求者继续执行操作 2** 成功,操作成功接收并处理 3** 重定向,需要进一步的操作以完成请求 4** 客户端错误,请求包含语法错误或无法完成 ...

  10. KVM 学习笔记

    查看虚拟化环境 (1)查看虚拟机环境 (2)查看kvm模块支持 (3)查看虚拟工具版本 (4)查看网桥