14_Response

回顾
  • tomcat服务器启动的时候会加载服务器中的项目,并为每个项目创建一个唯一的ServletContext对象
  • 在每个项目中有多个Servlet对象,每个Servlet对象都有一个ServletConfig对象,对应的是web.xml中的配置信息
大纲
  1. 完成文件下载
    • 实质是文件的拷贝
  2. 生成验证码(了解)
    • 了解验证码的原理
    • 到企业中,每个企业都有自己封装好的验证码代码,直接调用
    • 还有第三方机构提供的代码
HttpServletResponse
概述
  • 浏览器发送请求给服务器,服务器内核通过反射创建相应的Servlet对象
  • 同时将Http请求的参数封装到ServletRequest对象中,和创建一个默认的ServletResponse对象(有默认的返回地址,请求头等参数,可以自己修改,响应体默认是空的)
  • 学习通过HttpServletResponse修改响应行,响应头,响应体的信息
Response设置响应行的信息
  • 响应行包括(Http协议的版本,状态码,状态信息),我们只需要修改状态码
  • 设置响应行中的状态码
    • setStatus(int sc)
  • 开发中用的并不多,一般都由tomcat自动生成对应的状态码
Response设置响应头
  • 一般开发中用: serHeader(String name, String value)一个就够了
  • 设置响应头的方式有:
addHeader(String name, String value) 
addIntHeader(String name, int value) 
addDateHeader(String name, long date)
setHeader(String name, String value) 
setDateHeader(String name, long date) 
setIntHeader(String name, int value)
  • 其中,add表示添加,set表示设置
  • 虽然添加或者设置的时候有int和long值,但是通过抓包工具,响应头的数据最终还是转为字符串
  • add方法中一般只用addHeader
  • 如果添加了两次相同的头,则会把两次的内容连在一起
  • setHeader可以设置不存在的头,多次设置只会保留最新修改的,不会重叠
  • 真正的开发当中,一般只用setHeader
重定向
  • 浏览器访问Servlet1没有找到相应的资源,Servlet1告诉浏览器需要到Servlet2中找,然后浏览器拿到消息后再去连接Servlet2
  • 你找我借钱,我没有,不过我可以告诉你谁有,你找他借
  • 重定向特点:访问服务器2次或多次,浏览器的地址栏会发生改变
  • 重定向:
    • 状态码:302
    • 响应头:location代表重定向地址
httpServletResponse.setStatus(302);
httpServletResponse.setHeader("Location","/webProjectName/ServletName");
  • 上面代码中很多都是重复的,j2ee封装了一个更方便的方法: sendRedirect(url)
httpServletResponse.sendRedirect("/url");
定时刷新
//设置定时刷新头
httpServletResponse.setHeader("refresh","5;url=http://www.xxx.com");//时间是秒
使用js完成页面定时跳转
设置响应体
  • 响应体设置文本,获取字符流,通过write(String str)方法可以将字符流设置到response缓冲区中
  • 随后tomcat会将response缓冲区中的内容封装成http响应返回给浏览器
PrintWriter writer = response.getWriter();
writer.write("hello world");
  • 关于编码问题:如果我们写的是中文,则在浏览器端会显示乱码.
    • 因为我们写的时候默认是卸载response的缓冲区,在封装成http响应的时候,中文会经过编码转为对应的二进制,编码过程,tomcat用的码表是:ISO8859-1(西欧码表)
    • 解决:修改编码用的码表(utf-8),通知response要用哪张码表(在获取writer之前设置码表)
    • 客户端大部分默认的编码是本地的编码格式,如window系统默认是gbk
    • 为了让客户端默认用我们编码时用的码表解码,我们可以把编码格式加到http响应头中:Content-Type
response.setCharacterEncoding("utf-8");
responst.setHeader("Content-Type","text/html;charset=UTF-8");//character也可以

PrintWriter writer = response.getWriter();
writer.write("你好,世界");
  • 在开发中,一般只要写responst.setHeader("Content-Type","text/html;character=UTF-8")就可以,response自动把缓冲区的编码也改为utf-8(但是要了解,底层设置两部分,一是设置编码时的码表,二是告知浏览器用什么码表解码)
responst.setHeader("Content-Type","text/html;charset=UTF-8");//character也可以,但是服务端还是要定义编码,用charset就不用

PrintWriter writer = response.getWriter();
writer.write("你好,世界");
  • 为了简化,j2ee工程师又设置了简化的方法
responst.setContentType("text/html;charset=UTF-8");//character也可以,但是服务端还是要定义编码,用charset就不用

PrintWriter writer = response.getWriter();
writer.write("你好,世界");
response的outputStream
  • response.getWriter()只适合于文本类型的传输,如果需要传输图片,电影等类型,则不适合,需要用到IO操作
  • 服务器向客户端写字节:
ServletOutputStrean getOutputStream()
//InputStream is = this.getClass().getClassLoader().getResourceAsStream(path);//类加载器只能加载src下的资源,我们的资源放在WEB-INF中,只能用FileInputStream手动创建输入流
  • 通过该方法获得字节流,通过该字节流write(byte[] bytes)可以向response缓冲区写入字节
  • 再由tomcat服务器将字节内容组成Http响应返回给浏览器
  • 文件上传和文件下载用的路径都是绝对路径
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String path = getServletContext().getRealPath("WEB-INF/img/timg.jpg");
    //InputStream is = this.getClass().getClassLoader().getResourceAsStream(path);
    FileInputStream fis = new FileInputStream(path);
    ServletOutputStream os = response.getOutputStream();
    byte[] arr = new byte[1024];
    int length = 0;
    while((length=fis.read(arr))>0) {
        os.write(arr,0,length);
    }
    fis.close();
}
文件下载基本代码
  • 文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端
  • 什么情况下会文件下载
    • 通过a标签直接指向静态资源,如果浏览器可以解析,则直接浏览.如果浏览器不可以解析,则下载(解析能力跟浏览器的类型有关)
    • 浏览器不能解析的文件,就提供下载功能
  • 什么情况下需要在服务器端编写文件下载代码
    • 理论上,浏览器可以解析的代码需要编写文件下载代码
    • 开发中,不确定哪些可以解析哪些不可以解析,都编写下载代码
  • 但是为了防止浏览器帮你解析,需要告诉浏览器不要解析该文件
  • 我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式
    1. 告知浏览器文件的类型:response.setContentType(文件的MIME类型)
      • 客户端通过文件的MIME类型去区别文件类型(人看后缀,客户端看MIME)
    2. 2)告示浏览器文件的打开方式是下载
      • response.setHeader("Content-Disposition","attachment;filename=文件名称");
  • 下载的文件名有中文名,浏览器解析不了,页面在下载时会出现中文乱码或不能显示文件名的情况
    • 原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐 浏览器是Base64编码方式
    • 所里这里需要解决浏览器兼容性问题,解决浏览器兼容性问题的首要任务是要辨别访问者是ie还是火狐(其他)
    • 通过Http请求体中的一个属性可以辨别
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");                
}
repsonse细节点
  1. response获得的流对象不需要手动关闭,tomcat容器会帮我们关闭
  2. getWriter和getOutputStream不能同时调用
  3. 重定向后就不要往下写代码了
实现验证码功能
  • 验证码的图片是通过java代码动态生成的
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,932评论 6 13
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,799评论 25 707
  • Http协议详解 标签(空格分隔): Linux 声明:本片文章非原创,内容来源于博客园作者MIN飞翔的HTTP协...
    Sivin阅读 5,210评论 3 82
  • 线程的几种状态及状态之间的转换下面这张图描述的很清晰: 另外推荐大家一篇文章,这篇文章写的非常不错,有兴趣的也可以...
    牛逼的二进制阅读 1,793评论 0 0