Java Web中的request,response,重定位与转发的详解
request与response响应
Web服务器接收到客户端的http请求,其会对每一次的http请求分别创建应该代表请求的
request
对象,和一个代表响应的response
对象.request
是获取客户端提交的数据,response是向客户端提供数据.
request
- 一个
request
请求由以下数据组成- 请求方法:表示客户端将要执行的操作,例如
GET
,POST
,PUT
,DELETE
等等 - 请求URL:客户端想要访问资源地址
- 请求头:包含有关请求的元数据,如
Content-Type
,User-Agent
,Accept-Languge
- 请求体:其包括发送给服务器的数据,例如数据表单,JSON数据等等
- 请求参数:包含在URL中的参数,传递服务器所需的数据
- 请求方法:表示客户端将要执行的操作,例如
response
- 一个
response
响应包括以下几个数据- 状态码:一个三位数字的状态码,请求的结果,如
200 OK
,404Not Found
,500 Internal Server Error
等 - 响应头:
response
的响应头与request的请求头的数据类型是一致的,Content-Type
,User-Agent
,Accept-Languge
- 响应体:包含服务器返回给客户端的数据,例如HTML页面.JSON数据,图片等
- 状态码:一个三位数字的状态码,请求的结果,如
HttpServletRequest与HttpServletResponse
HttpServletRequest
和HttpServletResponse
分别是ServletReques
和ServletResponse
的子接口,Http接口是专门处理HTTP协议的接口
ServletReques
与ServletResponse
是Servlet API中的顶级接口,与HttpServletRequest
和HttpServletResponse
不同的是,前者是处理请求/响应的基本接口,其定义了多种请求/响应的接口可适用多种协议,不仅是HTTP请求
HttpServletRequest
以下主要介绍对于
HttpServletRequest
四个应用方面,其中也借鉴了同平台创造者@Evan Liu
获取客户端的信息的常用方法
String getRequestURL()
:返回客户端发出请求的完整URLString getRequestURI()
:返回请求行中部分资源名String getQueryString()
:返回请求行中的参数部分String getRemoteAddr()
:返回发出请求的客户端的IP地址String getMethod()
获得客户机请求方式getContextPath()
:获取工程虚拟目录的名称
Eg:
@WebServlet("/test")
public class MyHttpServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getRequestURL());
System.out.println(req.getRequestURI());
System.out.println(req.getQueryString());
System.out.println(req.getRemoteAddr());
System.out.println(req.getMethod());
System.out.println(req.getContextPath());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行POST请求业务逻辑");
}
获取请求头信息
String getHeaders(String var1)
:获取头信息的值,将其转化为一个字符串,var1
:请求头的名称,例如:
"Accept-Encoding"
,"User-Agent"
、"Content-Type"
等等Enumeration<String> getHeaders(String var1)
:获取头信息的值,返回应该Enumeration<String>
类型的数组Enumeration<String> getHeaderNames(String var1)
:获取所有头信息名称,返回应该Enumeration<String>
类型的数组Enumeration
:枚举接口,是一种特殊的数据类型,主要用于遍历集合元素,是个较老的技术,现在主流使用Iterator
和Iterable
eg:
@WebServlet("/test")
public class MyHttpServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("getHeaders:"+req.getHeaders("Accept-Encoding"));
//获取http请求头中的referer防盗链
System.out.println("getHeaders:"+req.getHeader("referer")); System.out.println("--------------------------------------------------");
Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements())
{
String name=headerNames.nextElement();
System.out.println(name+":"+req.getHeader(name));
} } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行POST请求业务逻辑");
}
}
获取请求参数信息
String getParameter(String name)
:获取一个指定名称的请求参数的值,没找到则返回null
String getParameterValues(String name)
:获取指定名称的请求参数的所有值,即一个参数有多值,则返回所有,没找到则返回null
Enumeration<String> getParameterNames()
:获取请求中的所有参数名Map<String, String[]> getParameterMap()
:获取请求中的所有参数及其映射
eg:
@WebServlet("/test")
public class MyHttpServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String parameter = req.getParameter("value");
String[] values = req.getParameterValues("value");
Enumeration<String> parameterNames = req.getParameterNames();
Map<String, String[]> parameterMap = req.getParameterMap();
System.out.println(parameter);
System.out.println(Arrays.toString(values));
while(parameterNames.hasMoreElements())
{
String str=parameterNames.nextElement();
System.out.println(str);
}
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String str = entry.getKey();
String[] string = entry.getValue();
System.out.print(str+":");
System.out.println(Arrays.toString(string));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行POST请求业务逻辑");
}
}
请求转发
在Java Web 请求转发是一个十分常用的技术,其用于在一个Web应用内部,从一个资源如(
Servlet
),跳转到另一个资源,实现资源的分布利用
请求转发的原理
- 当一个Servlet接收到客户端的请求后,其可以决定将请求转发给另一个资源来处理.这种情况下,原始请求的上下文如(请求参数,请求头等等) 都会传递到目标资源,客户端是无法察觉到发生了转发
转发方式
Java中,提供了一个
RequestDispatcher
接口,用于实现请求转发和请求包含,这在处理复杂的Web应用逻辑时非常有用
RequestDispatcher的主要方法
void forward(ServletRequest var1,ServletResponse var2
:将当前请求转发到指定的目标资源,传递原始请求和响应对象void include(ServletRequest var1, ServletResponse var2)
:将指定的目标资源包含到当前响应中,目标资源的输出会被合并到当前响应中
ServletRequest请求范围方法
Java Web开发中ServletRequest接口提供的方法可以让一些属性在一个请求的生命周期被多个资源共享
void setAttribute(String name, Object object)
:其用于将一个 <名称-对象> 对添加到请求范围,在之后的业务逻辑中使用- 底层原理:
- 存储原理:当调用了
setAttribute
方法时,ServletRequest
接口会创建一个内部映射Map,将其<名称-对象>对添加在其中,该Map是一个线程安全的数据结构,适于存储范围属性 - 作用范围:作用范围通常是一次HTTP请求的生命周期内,则说明存储在Map中的属性只能在处理当前的过程中可用,请求处理结束后,这些属性就自动销毁
- 共享属性:通过
setAttribute
存储的属性可以在处理不同阶段被多个资源访问,则意味着可以在不同的Servlet
之间共享数据
- 存储原理:当调用了
- 底层原理:
Object getAttribute(String name)
:用于获取指定名称的请求属性的值,没有检索到则访问null
viod removeAttribute(String name)
:用于从请求范围中删除指定名称的属性
转发的特性
- 服务器端操作:转发操作是服务器的操作,客户端不会察觉到, 浏览器的地址栏URL不会发生变化
- 相对路径:转发时通常使用相对路径来指定目标资源位置,目标资源必须位于同一个Web应用中
- 生命周期:请求转发发生在同一个请求生命周期中,异常转发后可以共享一个
HttpServletRequest
和HttpServletResponse
HttpServletResponse
HttpServletResponse
封装服务器向客户端发送响应数据信息
常用的response方法
void setStatus(int status)
:用于设置HTTP响应状态码,通常用于指示客户端是否成功以及如何处理响应,status
:HTTP响应状态码,如200 OK
和404 Not Found
void setHeader(String name, String value)
:设置一个带有给定名称和值的Header
,若name
已存在,则直接覆盖ServletOutputStream getOutputStream()
:获取一个ServletOutputStream
字节流对象,输出响应体内容PrintWriter getWriter()
:获取一个PrintWriter
字符流对象,输出响应体内容,PrintWriter
实际上继承了Writer
状态响应码
状态响应码用于表示服务器对客户端请求的响应状态,状态码都是有一个三位数字代码和一个简短的描述组成,状态码可分为五种:1xx,2xx,3xx4xx,5xx
1XX(信息状态码)
此类状态码表示请求已经被服务器接收,但仍需进一步处理
- 100 Continue:通常用于
POST
请求,表示服务器告知客户端已经接收了一部分,客户端可以继续发送剩余部分 - 101 Switching Protocols:切换服务器协议,通常用于将HTTP协议升级到WebSocket协议
- 100 Continue:通常用于
2XX(成功协议)
此类状态码表示请求已经被成功处理
- 200 OK:表示请求已经成功处理,响应中包含了请求的数据
- 201 Created:表示已经创建了一个资源,通常用于POST请求,当创建了一个资源返回
- 202 Accepted:表示服务器已经接受了请求,但仍未处理,通常用于异步处理
- 204 Not Content:表示服务器成功处理了请求,但没有返回内容
3XX(重定向状态码)
此类状态码表示客户端还要采用进一步操作来无参指示
301 Moved Permanently:表示服务器资源被永久性地转移到一个新的URL,客户端(浏览器)将自动地将资源重定向到新URL
302 Found (Previously "Moved Temporarily"):其表示请求的资源被暂时转移到一个新URL,同样客户端会自动将其资源重定向到新URL
4XX(客户端错误状态码)
此类状态码表示客户端的请求存在错误
- 400 Bad Request:其表示客户端发送的请求语法错误或无法被服务器正确解析理解
- 401 Unauthorized:其表示客户端尝试访问需要身份验证的资源,但未提供有效的认证信息
- 403 Forbidden:表示有足够的权限访问资源,但被服务器拒绝,
- 404 Not Found:服务器找不到请求的资源
- 405 Method Not Allowed:表示请求的方法不允许用于请求资源
5XX(服务器错误状态码)
- 500 Internal Server Error:通常表示服务器遇到了不可预计的情况,无法完成请求,通常表示服务器内部错误
- 501 Not Implemented:表示服务器不支持请求的方法,例如服务器可能不支持PUT方法
- 502 Bad Gateway:表示网关或代理工作的服务器接收到了无效的响应
- 503 Service Unavailable:表示服务器当前无法使用(超载或停机)
- 504 Gatew TimeOut:表示作为网关或代理工作的服务器没有及时从上游服务器收到请求
重定位
重定位(Redirect)是一个常见的技术,用于将一个客户端请求从一个资源重定位到另一个资源,重定位与转发不同,重定位会创建一个新的HTTP请求
重定位的方式
在Servlet API中,
HttpServletResponse
接口提供了一个方法实现重定位void sendRedirect(String location)
:将客户端重定位到相应的URL,location:目标URL地址
eg:
@WebServlet("/test01")
public class MyHttpServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置输出文字格式,即编码格式
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.println("<p>这是第一个servlet</p>");
//进行转发到/test02
resp.sendRedirect("/test02");
}
}
//
@WebServlet("/test02")
public class MyHttpServlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.println("<p>这是第二个servlet</p>");
}
}
当向浏览器访问/test01时,浏览器会接受到第一个Servlet的响应,接着会重定位到/test02.再次发起请求,客户端会看到两次跳转和以下界面
重定位的原理
- 服务器接收到请求后,会提供其HTTP响应码判断是否要进行重定位操作,若状态码为
302 Found
(或301 Moved Permanently
)会查看其响应头(Response Headers)
中的Location属性,并根据其进行重定位 - 客户端接收到重定位响应,解析出新的跳转位置时,会再次发起一次HTTP请求到新位置
sendRedirect()
实际是设置了请求头中的Status Code(状态响应码)和响应头中的Location属性
- 服务器接收到请求后,会提供其HTTP响应码判断是否要进行重定位操作,若状态码为
重定位与转发的区别
转发和重定向都是实现页面的跳转,他们都是访问一个Servlet时,Servlet会帮我们跳转到另一个界面,只是实现方法不同,以下内容借鉴了创造者 @萌小Q
- 从URL地址栏来说
forward
是服务器请求资源,服务器之间访问目标地址的URL,服务器将目标URL响应内容发送给客户端(浏览器),实际上浏览器不知道服务器发送的内容是从哪里来的,其操作是服务器实现的redirect
是服务器根据业务逻辑发送一个状态码,告知浏览器重新去请求新的URL,因此重定位地址栏的URL会相应改变
- 数据共享
- forward:被转发的页面和转发后的页面都可以共享
request
作用域里的数据 redirect
:不能共享数据
- forward:被转发的页面和转发后的页面都可以共享
- 用途方面
forward
:一般用于用户登录时,根据角色转发相应模板redirect
:一般用于用户注销登录时放回主页面或是跳转到其他网站等等
- 效能方面
forward
:较高效率redirect
:效率较低
底层本质区别
forward
(转发)是服务器行为,redirect
(重定向)是客户端行为
- 行为动作
forward
行为:客户端(Browser
)发起http请求→web服务器(例如Tomcat
)接收请求→调用其内部一个方法完成请求处理或转发动作→将请求响应的资源返回给客户端;对于forward,转发的路径必须是同一个web容器下的URL,不能转向到另一个web路径上,转递的是request
,转发认为浏览器只做了一次访问请求redirect
行为:客户端发送http请求→web服务器接收后发送302状态响应码和对于的location给客户端→客户端检查响应头发现是302响应,则在次发送一次http请求,请求的是location中新的URL→服务器根据请求响应相应的资源返回客户端,由于是浏览器重新发起请求,那跟中间的request传递没有关系,重定位是客户端至少做了两次访问操作
- 操作权限
forward
:是将服务器内部将一个request
或response
的处理权限,交付给另一个Servlet
redirect
:是客户端request A,服务器响应,并response回来,告诉浏览器你应该去B,重定向可以访问自己web应用以外的资源
- 注意事项
redirect
(重定向):跳转后必须加上return
要不然页面虽然跳转了但是还会执行跳转后面的语句forward
(转发):是执行了跳转页面下面的代码就不会在执行了
Java Web中的request,response,重定位与转发的详解的更多相关文章
- Nginx服务器中配置非80端口的端口转发方法详解
这篇文章主要介绍了Nginx服务器中配置非80端口的端口转发方法详解,文中使用到了Nginx中的proxy_pass配置项,需要的朋友可以参考下 nginx可以很方便的配置成反向代理服务器: 1 2 ...
- java Web中页面跳转方式之请求转发
1.在一个请求中跨越多个Servlet 2.多个Servlet在一个请求中,他们共享request对象.就是在Servlet01中setAttribute()保存数据在Servlet02中由getAt ...
- Java正则中为什么反斜线"\"需要用“\\\\”表示,原因详解。
首先,我们需要知道在java字符串和正则表达式中,“\”都具有特殊的含义. 一.在Java的字符串中"\"有两个功能 (一)代表特殊字符:\t代表制表符,\n代表换行....等. ...
- [原创]java WEB学习笔记43:jstl 介绍,core库详解:表达式操作,流程控制,迭代操作,url操作
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记58:Struts2学习之路---Result 详解 type属性,通配符映射
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- JDBC在Java Web中的应用
JDBC在Java Web中的应用 制作人:全心全意 在Java Web开发中,JDBC的应用十分广泛.通常情况下,Web程序操作数据库都是通过JDBC实现,即使目前数据库方面的开源框架层出不穷,但其 ...
- Java Web 中 过滤器与拦截器的区别
过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法u ...
- JAVA WEB 中的编码分析
JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...
- 深入分析Java Web中的编码问题
编码问题一直困扰着我,每次遇到乱码或者编码问题,网上一查,问题解决了,但是实际的原理并没有搞懂,每次遇到,都是什么头疼. 决定彻彻底底的一次性解决编码问题. 1.为什么要编码 计算机的基本单元是字节, ...
- 解决java web中safari浏览器下载后文件中文乱码问题
解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...
随机推荐
- JS的JSON.parse问题
这个问题,已经有非常多人说过,而且由来已久. 大家都提供了不少的解决方法,但是都不够彻底. 一)现在是什么情况 1.使用SpringMvc+ModelAndView+jsp传递值 由于业务需要,通过m ...
- CLR via C# 笔记 -- 异常和状态管理(20)
1. 异常是指成员没有完成它的名称所宣称的行动,异常类继承System.Exception. 2. .Net Framework 异常处理机制是用Microsoft windows提供的结构化异常处理 ...
- 使用 nginx 共享文件
1. 安装nginx 2. 在nginx的配置文件的server部分加上如下的配置: location /shared/ { autoindex on; autoindex_exact_size on ...
- Linux 内核:I2C子系统分析(1)基于子系统的驱动分析与实现
Linux 内核:I2C子系统分析(1)基于子系统的驱动分析与实现 背景 在学习高通平台的有关知识,看到一篇博客中介绍了GPIO模拟I2C设备,觉得挺有意思的. 看了看有关的实现,发现自己之前学习从L ...
- FFmpeg新旧接口对照使用一览
背景 根据例程学习调用ffmpeg 库方法的时候,发现了一堆警告. main.cpp:81:37: warning: 'AVStream::codec' is deprecated [-Wdeprec ...
- 扫描版PDF目录制作指南
目前网上找到的扫描版的电子书往往没有目录,这使得阅读变得非常困难.本文总结我的经验,介绍快速制作扫描版 PDF 目录的方法,以便更轻松地阅读扫描版电子书. 本文首先介绍手动制作目录的方法,之后介绍如何 ...
- Ubuntu20.04之Nvidia驱动安装
参考:https://blog.csdn.net/xiaokedou_hust/article/details/82187860,实际操作时和该博文有些出入,故作优化. s1.连接wifi,打开终端. ...
- ELK之Elastic-Search 整理(一):基础理论 与 DSL语法 及 Java操作ES
基础理论和DSL语法 准备工作 什么是ElasticSearch?它和Lucene以及solr的关系是什么? 这些是自己的知识获取能力,自行百度百科 下载ElasticSearch的window版 l ...
- GUI测试还能这么玩(Page Code Gen + Data Gen + Headless)
标签(空格分隔): GUI测试还能这么玩(Page Code Gen + Data Gen + Headless) 页面对象自动生成 在前面的文章中,我已经介绍过页面对象(Page Object)模型 ...
- TCP/UDP 协议和 HTTP/FTP/SMTP 协议之间的区别
前言 我们经常会听到HTTP协议.TCP/IP协议.UDP协议.Socket.Socket长连接.Socket连接池等字眼,然而它们之间的关系.区别及原理并不是所有人都能理解清楚. 计算机网络体系结构 ...