Response 和 Request
1. request 对象和 response 对象均由服务器创建.
2. 服务器处理请求的流程:
- 服务器每次收到请求时, 都会为这个请求开辟一个新的线程;
- 服务器会把客户端的请求数据封装到 request 对象中, request 对象就是请求数据的载体!
- 服务器还会创建 response 对象, 这个对象与客户端连接在一起, 它可以用来向客户端发送响应.
3. response 对象
3.1 response 对象向浏览器发送的内容包括:
- 响应行
- 响应头
- 空行
- 响应体
3.2 根据发送的内容, 查找 JavaEE API 文档的 javax.servlet.http 中的 HttpServletResponse 接口
3.2.1 响应行中的状态码
- 状态码: 200 表示成功, 302 表示重定向, 404 表示客户端错误, 500 表示服务器错误.
- 常用方法:
sendError(int sc);
: 发送错误状态码, 例如 404, 500sendError(int sc, String msg);
: 发送错误状态码和错误描述信息setStatus(int sc);
: 发送成功的状态码, 如 200, 302
3.2.3 响应头相关的方法
- 响应头是由键值对组成, 可能会存在一个键,一个值, 也可能会存在一个键对应多个值的情况.
- 响应头的键不区分大小写, 一般都是大小首字母.
- 常用方法:
setHeader(String name, String value);
: 适用于单值的响应头; (该方法较常用)addHeadet(String name, String value);
: 适用于一个名称多个值的响应头;setIntHeadet(String name, int value);
: 适用于单值的, 且值为 Int 类型的响应头;addIntHeader(String name, int value);
: 适用于多值的, 且值为 Int 类型的响应头;setDateHeader(String name, long value);
: 适用于单值的毫秒类型的响应头;addDateHeader(String name, long value);
: 适用于多值的毫秒类型的响应头;
// 示例:
// 发送 404 错误信息
response.sendError(404, "您要找的信息不存在!");
// 发送 302, 设置 Location 头, 通过访问 AServlet 完成重定向到 BServlet
response.setStatus(302);
response.setHeader("Location","/day10_1/BServlet"); // 请求URI: /项目名/Servlet 路径
// 第二种方式: 重定向
response.sendRedirect("/day10_1/BServlet");
// 设置文件大小
response.setIntHeader("Content-Length", 346);
// 设置定时刷新的响应头
response.setHeader("Refresh", "5;URL="/day10_1/CServlet");
// 浏览器缓存过期时间为 24 小时
response.setDateHeader("expires", 1000*60*60*24);
// 禁用浏览器缓存的设置方法 (下面的三个响应头需要一起使用, 以便覆盖所有的浏览器)
response.setHeader("Cache-Control", "no-cache");
response.setHeader("pragma", "no-cache");
response.setDateHeader("expires", -1); // -1 表示马上过期
// html 页面中在 <head> 标签内部中子标签 <meta> 可以替代响应头
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
3.2.4 响应体相关的方法
- 响应体通常是 html, 也可以是图片.
- response 的两个流, 用于向客户端响应内容:
- ServletOutputStream : 用来向客户端发送字节数据; API 位于 J2EE 文档中 javax.servlet
- PrintWriter : 用来向客户端发送字符数据! 需要设置编码类型; API 位于 J2SE 文档中 java.io
- 两个输出流不能同时使用!! 若同时使用,会抛出 IllegalStateException.
// 示例
// 使用 PrintWriter 发送字符数据
// 发送字符 "Hello World!"
response.getWriter().print("Hello World!");
// 使用 ServletOutputStream 发送字节数据(图片)
// 发送字符 "Hello World!"
String s = "Hello World!";
// 把字符转换成字节
byte[] bytes = s.getBytes();
response.getOutputStream().write(bytes);
// 发送 F 盘下 a.jpg
// 需要先用 IO 流将图片变成字节数组, 然后发送
// 需要使用 commons-io-1.4 jar 包
String path = "F:/a.jpg";
FileInputStream in = new FileInputStream(path);
byte[] bytes = IOUtils.toByteArray(in); // 将输入流中的字节读取到字节数组中.
response.getOutputStream().write(bytes);
request 对象
- 服务器将客户端所有的请求数据都封装到 request 对象中.包括:
- 请求行
- 请求头
- 空行
- 请求体(GET 没有请求体)
2. 常用方法 (JavaEE API 文档的 javax.servlet.http 中的 HttpServletRequest 接口)
2.1 获取常用信息
- 获取客户端IP:
request.getRemoteAddr();
- 获取客户端请求方式:
request.getMethod();
结果为 POST 或 GET
2.2 获取 HTTP 请求头
String getHeader(String name);
: 适用于单值请求头. (较常用)int getIntHeader(String name);
: 适用于单值 int 类型的请求头long getDateHeader(String name);
: 适用于单值毫秒类型的请求头Enumeration<String> getHeaders(String name);
: 适用于多值请求头
// 示例
// 获取客户端 IP
request.getRemoteAddr();
// 通过 User-Agent 识别用户浏览器类型
request.getHeader("User-Agent");
// 使用 Referer 请求头, 来防盗链
// Referer 用来告诉服务器,浏览器从哪个页面链接过来的
request.getHeader("Referer");
2.3 获取请求 URL
http://localhost:8080/day10_1/AServlet?username=zhangsan&password=aaa
- 获取协议:
String getScheme();
, 返回值为 http - 获取服务器名:
String getServerName();
, 返回值为 localhost - 获取服务器端口:
String getServerPort();
, 返回值为 8080 - 获取项目名:
String getContextPath();
, 返回值为 /day10_1 - 获取 Servlet 路径:
String getServletPath();
, 返回值为 /AServlet - 获取参数部分, 即问号后面的部分:
String getQueryString();
, 返回值为 username=zhangsan&password=aaa - 获取请求 URI, 等同于项目名+Servlet 路径:
String getRequestURI();
, 返回值为 /day10_1/AServlet - 获取请求 URL, 等于不包含参数的整个请求路径:
String getRequestURL();
, 返回值为 http://localhost:8080/day10_1/AServlet
2.4 获取请求参数
- 请求参数是由客户端发送给服务器的!!
- 请求参数有可能在请求体中(POST 请求), 也可能是在 URL 之后(GET 请求);
- 一个请求参数可以对应一个值或多个值.
- 获取指定名称的请求参数值, 适用于单值请求参数:
String getParameter(String name);
(较常用) - 获取指定名称的请求参数值, 适用于多值请求参数:
String[] getParameterValues(String name);
- 获取所有请求参数名称:
Enumeration<String> getParameterNames();
- 获取所有请求参数, 其中 key 为参数名, value 为参数值:
Map<String, String[]> getParameterMap();
(较常用)
2.5 请求转发和请求包含
- 有时一个请求需要多个 Servlet 协作才能完成, 所以需要在一个 Servlet 跳转到另一个 Servlet!
- 一个请求跨多个 Servlet, 需要使用转发和包含;
- 请求转发: 由下一个 Servlet 完成响应体! 当前 Servlet 只可以设置响应头! (即第一个 Servlet 留头不留体);
- 请求包含: 由两个 Servlet 共同完成响应体! (第一个 Servlet 请求头和请求体都留);
- 无论是请求转发还是请求包含, 都发生在一个请求范围内! 使用的是同一个 request 和 response!!!
// 首先使用 request 对象获取转发器(RequestDispatcher 对象)
// 该方法的参数是被转发或包含的 Servlet 路径, 该路径也就是在 web.xml 中 <url-pattern>/AServlet</url-pattern> 配置的
RequestDispatcher rd = request.getRequestDispatcher(String path);
// 请求转发 (使用较多)
rd.forward(request, response);
// 请求包含
rd.include(request, response);
2.6 request 域
- Servlet 中三大域对象: request, session, application(ServletContext), 它们都具有如下三个方法:
void setAttribute(String name, Object value);
设置(添加)域属性void getAttribute(String name);
获取域属性void removeAttribute(String name);
删除域属性
- request 域必须是在同一个请求范围内;
- 同一个请求范围内, 前一个 Servlet 使用
request.setAttribute()
保存值, 后一个 Servlet 调用request.getAttribute()
来获取值. - 请求参数是客户端向服务器发送请求时,自己带过来的内容, 只能使用 get 方法, 从 request 对象中获取.
而 request 域中,存放的是属性,不是请求参数. 属性也就是 Servlet 和 Servlet 在转发或包含时, 传递值使用的.
3. 请求转发和重定向的区别:
- 请求转发是一个请求一次响应, 而重定向是两次请求两次响应;
- 请求转发地址栏不发生变化, 而重定向会显示后一个请求的地址;
- 请求转发只能转发到本项目其他 Servlet, 而重定向不只能重定向到本项目的其他 Servlet, 还能定向到其他项目;
- 请求转发是服务器行为, 只需给转发的 Servlet 路径, 而重定向需要给出 requestURI, 即包含项目名;
- 请求转发比重定向效率高, 因为是一个请求;
**参考资料:**
- [JavaWeb 视频教程](https://www.bilibili.com/video/av12762289/#page=2)
- [JavaEE 6.0 文档](http://tool.oschina.net/apidocs/apidoc?api=javaEE6)
- [commons-io-2.5 jar 包](http://commons.apache.org/proper/commons-io/download_io.cgi)
Response 和 Request的更多相关文章
- 2014-08-22 关于Response、Request等对象在cs文件中的使用
今天是在吾索实习的第33天.已经有一段时间没写过博客了,今天突然想起个值得分享的东西,所以又华丽地回归了. 废话不多说了,直奔主题.我们会发现,在我们在cs文件中,直接使用Response.Reque ...
- response和request
请求响应流程图 response response是用来向客户端响应的对象! 需要回忆一下http响应内容: l 首行:状态码 l 响应头: 1头1值,1头多值: l 响应体(正文):html ...
- java web 中有效解决中文乱码问题-pageEncoding与charset区别, response和request的setCharacterEncoding 区别
这里先写几个大家容易搞混的编码设置代码: 在jsp代码中的头部往往有这两行代码 pageEncoding是jsp文件本身的编码contentType的charset是指服务器发送给客户端时的内容编码J ...
- Servlet中response、request乱码问题解决
Java Web(二) Servlet中response.request乱码问题解决 三月不减肥,五月徒伤悲,这就是我现在的状态,哈哈~ 健身.博客坚持. --WH 一.request请求参数出现 ...
- Java Web之Servlet中response、request乱码问题解决
Java Web之Servlet中response.request乱码问题解决 一.request请求参数出现的乱码问题 get请求: get请求的参数是在url后面提交过来的,也就是在请求行中, ...
- net1:post,get方式传值,读写cookie,读XML文件,写script语句,跳转页面,response与request类
原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...
- 浅谈response和request方法
一:概述 Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. 按这个理解的话一次请求生成一个request和res ...
- response和request的区别以及常见问题解决
request是请求,即客服端发来的请求 response是响应,是服务器做出的响应 --------------------------------------------------------- ...
- Webform(五)——内置对象(Response、Request)和Repeater中的数据增删改
一.内置对象 (一)Response对象 1.简介:response 对象在ASP中负责将信息传递给用户.Response对象用于动态响应客户端请求,并将动态生成的响应结果返回到客户端浏览器中,使用R ...
- Response、Request、QueryString,repeater添加,修改,删除数据
内置对象: Response对象:响应请求,Response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应.Response.Write("<script>a ...
随机推荐
- atitit.验证码识别step2------剪贴板ClipBoard copy image图像 attilax总结
atitit.验证码识别step2------剪贴板ClipBoard copy image图像 attilax总结 剪贴板(ClipBoard)是内存中的一块区域,是Windows内置的一个非常有用 ...
- [docker]搭建私有registry
导入导出镜像比较麻烦,共享镜像占了工作中一大部分时间. 搭建了个本地registry, 不支持用户名密码验证的 和 支持用户名密码验证的两种. 参考: https://docs.docker.com/ ...
- 使用GitHub做个人博客
前言 用过市面上主流的blog程序,也用Django自己写过开源的博客程序July(170+Star),慢慢的发现没太多精力去打理维护,干脆直接放GitHub当静态页面算了,之前也用过Hexo.jek ...
- linux下Oracle数据库实例开机自启动设置
linux下数据库实例开机自启动设置 1.改动/oratab [root@org54 ~]# vi/etc/oratab --把N改为Y,例如以下提示 # This file is used ...
- OSGi规范概要
目前最新的OSGi规范是2012年7月发布的Release 5,Version5.0(后文简称为R5.0)版本,该规范定义了Java模块化系统所涉及的各种场景(开发.打包.部署.更新和交互等),以及其 ...
- Java的ThreadContext类加载器的实现
疑惑 以前在看源码的时候,总是会遇到框架里的代码使用Thread.currentThread.getContextClassLoader()获取当前线程的Context类加载器,通过这个Context ...
- python学习笔记1--python简介
Python翻译中文是蟒蛇.发明人guido喜欢蟒蛇马戏团,故起名python. python发展简史: --CNRI时期.CNRI资助Python发展的重要单位,python1.5版之前的成果大部分 ...
- Intellij IDEA常用快捷键整理
ps:使用Intellij IDEA编辑器有蛮长一段时间了.哈哈.整合一下常用的快捷.避免自己以后还要再找. 顺序大概就是从上到下的 Alt + ENTER : 自动修正,提示Alt + Insert ...
- hdu6060 RXD and dividing 贪心
/** 题目:hdu6060 RXD and dividing 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6060 题意:贪心 给定一颗树,n个节点,编 ...
- UVA 11732 "strcmp()" Anyone? (Trie)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...