Java web每天学之Servlet工作原理详情解析

Posted shsxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java web每天学之Servlet工作原理详情解析相关的知识,希望对你有一定的参考价值。

上篇文章中我们介绍了Servlet的实现方式以及Servlet的生命周期,我们这篇文章就来介绍一下常用对象。

点击回顾:《Java Web每天学之Servlet的工作原理解析》;《Java Web每天学之Servlet的工作原理解析(二)

一、HttpServletRequest对象

1、介绍
HttpServletRequest对象:主要作用是用来接收客户端发送过来的请求信息,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service()方法中形参接收的是HttpServletRequest接口的实例化对象,表示该对象主要应用在HTTP协议上,该对象是由Tomcat封装好传递过来。

HttpServletRequest是ServletRequest的子接口,ServletRequest只有一个子接口,就是HttpServletRequest。既然只有一个子接口为什么不将两个接口合并为一个?

从长远上讲:现在主要用的协议是HTTP协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承ServletRequest接口就行了。

在HttpServletRequest接口中,定义的方法很多,但都是围绕接收客户端参数的。
但是怎么拿到该对象呢?不需要,直接在Service方法中由容器传入过来,而我们需要做的就是取出对象中的数据,进行分析、处理。

2、常用的方法
请求方式+url+版本号
getRequestURL:返回客户端发出请求时的完整URL
getRequestURI:返回请求行中的资源名部分(项目名称开始)
getQueryString :返回请求行中的参数部分
getMethod:得到客户端请求方式
getProtocol:获取HTTP版本号
getContextPath:获取webapp名字

获取客户端若干消息头
getHeader (String name):获取单个请求头内容
Enumeration<String> getHeaderNames():获取所有的请求头名称集合

获得客户机请求参数(客户端提交的数据)
getParameter(name):获取指定名称的参数值,这是最为常用的方法之一。
getParameterValues(String name):获取指定名称参数的所有值数组。它适用于一个参数名对应多个值的情况:如页面表单中的复选框,多选列表提交的值。

getParameterNames():返回一个包含请求消息中的所有参数名的Enumeration对象。通过遍历这个Enumeration对象,就可以获取请求消息中所有的参数名。

getParameterMap():返回一个保存了请求消息中的所有参数名和值的Map对象。Map对象的key是字符串类型的参数名,value是这个参数所对应的Object类型的值数组

3、请求乱码解决
由于现在的request属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置request中的编码方式,告诉服务器以何种方式来解析数据。

①req.setCharacterEncoding("UTF-8");这种方式只针对POST有效
②new String(req.getParameter(name).getBytes(“ISO-8859-1”));
Tomcat8之后GET不会出现乱码
Tomcat8及以上 Get 不会乱码,不用管
技术分享图片

4、跳转
request.getRequestDispacther(“要跳转的地址”).forword(request,response);
请求转发,服务器跳转,地址栏的URL不变。

在写路径时,以/开头或者 http://都是绝对路径,不以/开头就是相对路径,在请求转发时,”/”代表服务器路径+站点名,即http://localhost:8080/站点名

请求转发的过程:
客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法,把请求转发给指定的test.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完成的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在jsp中都能取出来,因此,jsp能把结果getAttribute()出来,getAttribute()出来后执行完把结果返回给客户端。整个过程是一个请求,一个响应。

5、request域对象
通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。
request.setAttribute():设置request域对象内容
request.getAttribute(String name):获取指定request域对象内容
request.removeAttribute(String name):删除指定request域对象

二、HttpServletResponse对象

1、介绍
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。

request和response对象既然代表请求和响应:获取客户端数据,通过request对象;向客户端输出数据,通过response对象。

HttpServletResponse的主要功能用于服务器对客户端的请求进行响应,将WEB服务器处理后的结果返回给客户端。service()方法中形参接收的是HttpServletResponse接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

2、常用方法
addCookie(Cookie cookie):将指定的Cookie加入到当前的响应中
addHeader(String name,String value):将指定的键值加入到响应头信息中
containsHeader(String name) :返回一个布尔值,判断响应的头部是否被设置
encodeURL(String url):编码指定的URL
sendError(int sc):使用指定状态码发送一个错误到客户端
sendRedirect(String location):发送一个临时响应到客户端,重定向
setHeader(String name,String value):将给出的名字和值设置响应的头部
setStatus(int sc):给当前响应设置状态
setContentType(String ContentType):设置响应的MIME类型
getWriter():获取输出字符流
getOutputStream():获取输出的字节流

3、设置头信息
1)、刷新、跳转页面
所有头信息都是随着请求和回应自动发送到服务器端(客户端),在response中一个比较常用的头信息就是刷新的指令,可以完成定时刷新的功能。
resp.setHeader("refresh","2");

对于刷新的头信息,除了定时的功能外,还具备了定时跳转的功能,可以让一个页面定时跳转到一个指定的页面。(已经注册成功,两秒后跳转到登陆页面)
response.setHeader("refresh","3;URL=ok.html");

但是这种跳转不是万能的,有时候根本就无法进行跳转操作,返回后刷新不会跳转;
对于这种定时跳转的头信息,也可以采用HTML的方式进行设置,HTML本身也可以设置头信息。(客户端跳转)
<meta http-equiv="refresh" content="3;http://www.shsxt.com>

2)、返回状态码
setStatus方法用来设置Servlet向客户端返回的状态码,它用来设置没有出错的状态,通常不使用。如果Servlet运行出错,Servlet可以使用sendError方法设置状态码,如sendError(int sc)方法设置错误状态代码。sendError(int sc,String msg)方法除了设置状态码,还向客户发出一条错误信息。
3)、添加Cookie
addCookie方法可以在Web服务器响应中加入Cookie对象,这个对象将被浏览器所保存。Cookie机制也被用来维护会话状态。
4、跳转
response.sendRedirect(“要跳转的路径”);
通过response也可以进行跳转,该种跳转称为请求重定向,属于客户端跳转,地址栏改变,存在两个请求。请求中的参数不能在此种跳转间传递。
在写路径时,以/开头或者http://都是绝对路径,不以/开头就是相对路径,在重定向时,”/”代表服务器路径,即http://localhost:8080

5、重定向过程:
客户浏览器发送http请求--->web服务器接受后发送302状态码响应及对应新的location给客户浏览器-->浏览器发现是302响应,自动再发送一个新的http请求,请求的url是新的location地址-->服务器根据此请求寻找资源并发送给客户。

6、响应乱码解决
当服务器端响应给客户端中文时,可能存在乱码
两种方式响应回数据:PrintWriter 和 ServletOutputStream
getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
PrintWriter():一定乱码,服务器自动使用ISO-8859-1编码,通过如下方式解决乱码
response.setCharacterEncoding("utf-8"); 
response.setHeader("content-type", "text/html;charset=utf-8");
一句顶两句:
response.setContentType("text/html;charset=utf-8"); 
OutputStream() :可能乱码

7、使用OutputStream流输出中文注意问题:
服务器端,数据输出的编码方式,就是客户端打开的编码方式
例:outputStream.write("中国".getBytes("utf-8"));使用OutputStream流向浏览器输出中文,编码方式是utf-8;此时客户端浏览器也要以utf-8的编码打开,否则会出现中文乱码。在服务器端控制客户端浏览器以utf-8的编码方式显示,此时既可以通过上述解决PrintWriter 的方式,也可以通过设置响应头信息的方式:
response.setHeader ("content-type", "text/html;charset=UTF-8");

三、HttpSession对象
1、介绍
HttpSession对象是javax.servlet.http.HttpSession的实例,该接口并不像HttpServletRequest或HttpServletResponse还存在一个父接口,该接口只是一个纯粹的接口。因为session属于HTTP协议的范畴。

对于服务器而言,每一个连接到它的客户端都是一个session,servlet 容器使用此接口创建 HTTP 客户端和 HTTP 服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个session中,最重要的就是属性的操作
session无论客户端还是服务器端都可以取得,若重新打开一个新的浏览器,则无法取得之前设置的session,因为每一个session只保存在当前的浏览器当中,并在相关的页面取得。

2、使用
常用方法
setAttribute(String name,Object value):将value对象以name名称绑定到会话
getAttribute(String name):取得name的属性值,如果属性不存在则返回null
removeAttribute(String name):从会话中删除name属性,若不存在不会执行,也不会抛处错误。
Enumeration getAttributeNames():返回和会话有关的枚举值
invalidate():使会话失效,同时删除属性对象
isNew():用于检测当前客户是否为新的会话
long getCreationTime():返回会话创建时间
getLastAccessedTime():返回会话时间内web容器接收客户最后发出的请求时间
int getMaxInactiveInterval():返回在会话期间内客户请求的最长时间为秒
setMaxInactiveInterval(int seconds):允许客户客户请求的最长时间
ServletContext getServletContext():返回当前会话的上下文环境,ServletContext对象可以使Servlet与web容器进行通信
String getId():返回会话期间的识别号

Session:默认是在第一次使用Session时被创建
Cookie: 大部分都是通过服务器主动(程序手动)设置到浏览器的, 只有JSESSIONID是服务自己设定的, 不需要程序员操心
session id

对于每一个用户而言,实际上都表示一个个不同的session,服务器通过session id来区分这些用户,即每一个通过浏览器连接到服务器上的用户都会由服务器分配一个唯一的不会重复的编号。
cookie自动设置的JSESSIONID的值就是每一个用户的session id,所以session在进行操作的时候用到了cookie的处理机制。

session id的结束
① 生命周期到期(默认一次浏览器的打开与关闭)
②非正常关闭服务器session销毁 
正常关闭服务器,session对象不会被销毁,而是会被序列化到磁盘上 
工作空间work目录下 SESSION.ser
③ 调用session的 invalidate() 方法 
session在所有的项目开发中,用得最多的地方就是登陆验证及注销操作功能
3、session域对象
一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共
享session中的数据。
request.getSession().setAttribute():设置session域对象内容
request.getSession().getAttribute(String name):获取指定session域对象内容
request.getSession().removeAttribute(String name):删除指定session域对象

四、ServletContext对象
1、介绍
一个web应用只有一个ServletContext对象,所有的servlet都共享这个ServletContext对象,又称为Application对象。WEB容器在启动时,会为每个WEB应用程序创建一个对应的ServletContext对象,其代表当前WEB应用。ServletContext定义了一组方法,servlet 使用这些方法与其他 servlet 容器进行通信,ServletContext 对象包含在 ServletConfig 对象中,ServletConfig对象在初始化 servlet 时由 web 服务器提供给 servlet。

2、常用方法
getInitParameter(String name):获取初始化参数
getResource(String parh)方法:其中path必须是/开头,代表当前web应用程序的根目录。返回返回的一个代表某个资源的URL对象。
 getResoutceAsStream(String parh):返回文件流。这个好处是可以使用相对于根目录的路径访问到web目录下的所有文件,而不必知道绝对路径。
getContextPath():得到web应用的路径
getRealPath():获取绝对路径

3、servletcontext域对象
ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。
request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。所以,为了节省空间,提高效率,ServletContext中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。
request.getServletContext().setAttribute():设置域对象内容
request.getServletContext().getAttribute(String name):获取域对象内容
request.getServletContext().removeAttribute(String name):删除域对象

上海Java培训感谢您的阅读,转载请注明出处,请多多关注支持,陆续Java相关技术文章奉上!












































以上是关于Java web每天学之Servlet工作原理详情解析的主要内容,如果未能解决你的问题,请参考以下文章

JAVA Web工作原理

Servlet 工作原理解析

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器过滤器等Web组件以及MVC架构

jsp工作原理

Java Web基础:JSP工作原理和基础概念

servlet入门学习之生命周期