Request和Response

   学习的过程中 , 慢慢的发现基础很重要 , 因为很多被认为很高深的东西往往也只是对基础东西的封装而已 , 下面来稍微回顾一下 Request Response 的知识
服务器如何处理客户端请求
当客户端向服务器发送请求时,服务器是如何将请求信息传递给 Servlet Servlet 又是通过什么将响应送给客户端。带着这些问题,我们来看下面这张图

  请求响应流程图
由图可知,服务器向 Servlet 传递了两个对象,分别是 request 对象和 response 对象。现在我们来分析一下请求响应的流程。具体如下:
(1) 当客户端向服务器发送请求时,服务器会先创建两个对象: request 对象和 response 对象。其中 request 对象中封装的是请求信息, response 是用来向客户端响应信息。
(2) 创建后,服务器会将两个对象作为参数传递到客户端请求的 Servlet service() 方法中, Servlet 就可以从 request 对象中获取请求信息;处理之后,使用 response 向客户端响应信息。
注意
我们知道 Servlet 是单例的,当多个用户同时请求一个 Servlet 时,服务器会为每个请求开启一个线程去访问 Servlet ,当请求完毕之后, request response 死亡;再次访问时,服务器再创建新的 request response 对象,因此这两个对象的生命周期很短暂。
 
request 对象的方法
request 对象
在服务器如何处理客户 端请求 中的图中,我们可以了解 request 对象是当客户端向服务器端发送请求后,服务器为本次请求创建出 request 对象,并在调用 Servlet service() 方法时,将该对象传递给 service() 方法。 request 对象中封装了客户端发送过来的所有请求数据。下面通过一张图来了解客户端请求服务器的请求响应过程,如图:

请求响应过程
request 对象常用 API
request 对象的类型是 HttpServletRequest ,该类中定义了很多与 http 协议相关的方法。比如获取请求头信息、请求方式、客户端 ip 地址等信息。下面介绍 request 对象常用的 API ,如下:
(1) 常用信息
  • String getRemoteAddr():获取客户端ip地址;
  • String getMethod():获取客户端请求方式,例如:postget
(2) 获取请求头信息
  • String getHeader(String name):获取单值的请求头的值;
  • int getIntHeader(String name):获取单值int类型的请求头的值;
  • getDateHeader(String name):获取单值long类型的请求头的值;
  • Enumeration<String> getHeaders(String name):获取多值请求头的值,返回值是Enumeration类型。
下面通过一个案例,来学习如何使用 request 对象的方法获得客户端 ip 地址、请求方式以及浏览器类型。具体如下:
(1) 创建 web 应用, Example06 ,在该应用下新建一个 Servlet 类, TestServlet ,主要代码如例 1-1 所示:
1-1 TestServlet.java
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
         // 获取客户端的 ip 地址
String ip=request.getRemoteAddr();
// 获取客户端的请求方式
String method=request.getMethod();
// 获取 User-Agent 请求头的值 , 该请求头是表明客户端浏览器的类型
String userAgent=request.getHeader("User-Agent");
System.out.println("ip:"+ip);
System.out.println("method:"+method);
System.out.println("User-Agent:"+userAgent);
}
}
(2)TestSerlvet 类在 web.xml 文件其访问路径配置为:“ /TestServlet “。
(3) Example04 发布到 Tomcat 服务器,然后启动服务器,在浏览器地址栏上输入: http://localhost:8080/Example06/TestServlet ,控制台打印结果如图 所示:


中,控制台打印的浏览器信息为: User-Agent Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; qdesk 2.4.1265.203; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.3) 。该信息中包含以下几点:
  • Windows NT 6.1:操作系统信息
  • MSIE 8.0:浏览器为IE,版本8.0
(4) TestServlet doGet() 方法略加修改,具体如例 1-2 所示:
1-2 TestServlet.java
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
         // 获取客户端的 ip 地址
String ip=request.getRemoteAddr();
// 获取客户端的请求方式
String method=request.getMethod();
// 获取 User-Agent 请求头的值 , 该请求头是表明客户端浏览器的类型
String userAgent=request.getHeader("User-Agent");
System.out.println("ip:"+ip);
System.out.println("method:"+method);
System.out.println("User-Agent:"+userAgent);
if(userAgent.toLowerCase().contains("chrome")) {
System.out.println("hello " + ip + ", you use google");
} else if(userAgent.toLowerCase().contains("firefox")) {
System.out.println("hello " + ip + ", you use firefox");
} else if(userAgent.toLowerCase().contains("msie")) {
System.out.println("hello:" + ip + ", you use IE");
}
}
}
(5) 重启服务器,在浏览器中再次访问 TestServlet ,控制台打印结果如图 所示:

控制台打印结果
(6) 使用浏览器,控制台打印结果如图 所示:

 
response 如何发送状态码
在服务器如何处理客户端请求中,我们了解, request 对象中封装了请求信息,使用 response 对象可以向客户端响应消息。在 Http 协议详解之响应 中,我们知道响应首行信息中包含了响应状态码,现在,我们要谈的就是如何使用 response 向客户端发送状态码。
response 对象的类型是 HttpServletResponse Servlet 的生命周期方法之一 service() 方法,它的两个参数的类型分别是 ServletRequest ServletResponse 。其中 HttpServletResponse ServletResponse 是子与父的关系,在 HttpServlet 类中,生命周期方法 service() 将它的参数都强转成 HttpServletRequest 类型和 HttpServletResponse 类型。
ServletRequest ServletResponse 是与协议无关的两个接口,而 HttpServletRequest HttpServletResponse 是与 http 协议有关的两个接口。
下面我们来了解 HttpServletResponse ,首先查看该接口的 API ,如图所示:

 HttpServletResponse 接口方法中,有三个方法被红色标注,它们是发送状态码的相关方法,与 Http 协议相关,因此该方法是在 HttpServletResponse 类中定义。
接下来对着三个方法进行分析,如下所示:
(1)void sendError(int sc)
                   该方法是向客户端发生错误的状态码,例如 404 500 等。      
(2)void sendError(int sc,java.lang.String msg)
                   该方法是向客户端发送错误的状态码,并且添加错误信息,例如, 404 ,您访问的资源不存在。
(3)void setStatus(int sc)
                  该方法是向客户端发送成功的状态码,还可以用来发送 302 状态码。
下面我们来看一个案例,使用 response 向客户端发送 404 状态码,具体如下:
(1) 创建 web 应用, Example01 ,在该应用中新建一个 Servlet 类, StatusServlet ,主要代码如例 1-1 所示:
1-1 StatusServlet.java
public class StatusServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
            response.sendError(404," 您访问的资源不存在 ");
}
}
(2)StatusServlet web.xml 文件中配置的访问路径是“ /StatusServlet ”;
(3) Example10 发布到 Tomcat 服务器中,然后启动服务器,在浏览器地址栏上输入: http://localhost:8080/YouProject/StatusServlet ,浏览器显示结果如图所示:

图浏览器显示结果
由图所示,在 StatusServlet 类中,使用 response 发送 404 状态码发送成功,这里要注意的是,当使用 response setStatus(int sc) 方法发送 404 状态码时,不起任何作用。
response 发送响应头相关方法介绍
响应信息都是由 response 发送给客户端的,今天的主要讨论的内容就是学习使用 response 发送响应头的相关方法。
响应头是以键值对的形式存在,例如: Content-Type:text/html;charset=utf-8 等。一般情况下,响应头都是一个名称对应一个值,但是也会存在特殊情况:一个名称对应多个值。这种情况很少见。对响应头进行设置是通过 response 的以下方法实现的,如下表所示:
response 设置响应头相关方法

方法名

方法描述

setHeader(String name,String value )

该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值.

addHeader(String name,String value)

该方法是设置有多个值的响应头,参数含义同上

setIntHeader(String name,int value)

该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数

addIntHeader(String name,int value)

该方法是设置有多个值且值的类型为int类型的响应头

setDateHeader(String name,long value)

该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间

addDateHeader(String name,long value)

该方法是设置有多个值且值的类型为long类型的响应头

由表 1-1 所示,可以设置响应头有以上 6 中方法,其中最常用的方法就是 setHeader(String name ,String value) 。下面我们通过以下几个小例子来了解如何使用这些方法:
(1)setHeader(String name ,String value)
     response.setHeader(“Content-Type”,”text/html;charset=utf-8”) ,设置 Content-Type 响应头;
(2)addHeader(String name,String value)
 response.addHeader(“xxx”,”XXX”)
 response.addHeader(“xxx”,”SSS”) 这里的 xxx 是表示某一响应头;
(3)setIntHeader(String name ,int value ):
     response.setIntHeader(“Context-Length”,888) ;通知客户端响应内容长度为 888 个字节;
(4)setDateHeader(String name,int value )
     response.setDateHeader(“expires”, 当前时间 +1000*60*60*24) ,设置过期时间为一天;
重定向
什么是重定向
所谓的重定向是将请求重新定个方向转到其他位置。例如,客户端访问 AServlet ,然后立刻自动访问 BServlet 。这个过程其实就是重定向。下面通过一张图来了解重定向,如图 1-1 所示:

重定向
由图 可知,重定向共有两次请求,两次响应。当客户端接收到 AServlet 的响应之后立刻去请求 BServlet ,这个过程很迅速。可以发现,地址栏发生变化,由 AServlet 变成 BServlet
 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码海拾贝2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值