简单说说Servlet,并分析面试官喜欢的Servlet执行原理
yuyutoo 2024-11-05 13:26 4 浏览 0 评论
Servlet
Servlet简介
Server + let 意为:运行在服务器端的小程序。 Servlet实际上就是一个接口。
- 狭义上的Servlet,指的就是Servlet接口
- 广义上的我们认为凡是实现Servlet接口的类,我们都称他是一个Servlet *****
- Servlet的作用:*
- 接收用户发送的请求
- 调用其他的java程序来处理请求
- 根据处理结果,返回给用户一个页面
Servlet的HelloWorld
- 创建一个类并实现Servlet接口
- 在web.xml文件中对Servlet进行配置
<servlet>
<servlet-name>别名</servlet-name>
<servlet-class>全类名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>别名</servlet-name>
<url-pattern>需要servlet处理的请求地址</url-pattern>
</servlet-mapping>
**Servlet的三个名字**:
<servlet-name>
- Servlet的别名,程序员通过别名对Servlet进行配置
<servlet-class>
- Servlet的全类名,服务器通过全类名来创建Servlet的实例
<url-pattern>
- Servlet映射的请求地址,用户通过该地址访问Servlet
Servlet的生命周期
Servlet的生命周期,指Servlet的对象从被创建到被销毁的过程。
Servlet的生命周期方法:
1.构造器:
- Servlet第一次处理请求时,会调用构造器,来创建Servlet实例。
- 只会调用一次,Servlet是单例模式,它是以多线程的方式调用service()方法.
- -Servlet不是线程安全,所以尽量不要在service()方法中操作全局变量
- 2.init()方法*:
- 构造器调用之后马上被调用,用来初始化Servlet,只会调用一次
- 3.service()方法*:
- Servlet每次处理请求时都会调用service()方法,用来处理请求,会调用多次。
- 4.destroy()方法*:
- Servlet对象销毁前(WEB项目卸载时)调用,用来做一些收尾工作,释放资源。
相关接口
ServletConfig 代表:当前Servlet的配置信息,每一个Servlet都有其唯一对应的ServletConfig。
<servlet>
<servlet-name>AServlet</servlet-name>
<servlet-class>com.atguigu.servlet.AServlet</servlet-class>
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123123</param-value>
</init-param>
</servlet>
获取:由Tomcat服务器创建,最终作为参数传递到init()方法中,我们可以在init()方法直接使用。 当我们通过继承HttpServlet创建Servlet时,由于父类已经实现ServletConfig接口, 所以我们可以在Servlet中直接调用ServletConfig的方法。
功能:
- 获取Servlet的别名
- 获取当前Servlet的初始化参数。
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123123</param-value>
</init-param>
- 获取当前WEB应用的ServletContext对象。
ServletContext
代表:当前的WEB应用,一个WEB应用对应一个唯一的ServletContext对象, ServletContext对象在项目启动时创建,在项目卸载时销毁。
获取:通过ServletConfig的getServletContext()方法获取。
功能: 【1】 可以获取整个WEB应用的初始化参数
<context-param>
<param-name>phone</param-name>
<param-value>1388888888</param-value>
</context-param>
【2】 可以获取资源的真实路径(物理路径),主要在文件的上传和下载时使用。 【3】可以作为一个域对象在不同的web资源之间共享数据。
GenericServlet
- 通用Servlet的父类
- 相比Servlet接口GenericServlet更加简单一些,但是我们最终实际上使用的HttpServlet
HttpServlet
- HttpServlet继承了GenericServlet,而GenericServlet实现Servlet接口
- 所以我们可以同构继承HttpServlet来创建一个Servlet。
- HttpServlet重写service()方法:
- 在该方法中先将ServletRequest和ServletResponse 强转为了HttpServletRequest和HttpServletResponse。然调用重载的service()方法,并将刚刚强转得到对象传递到重载的方法中。 如果是GET请求,则调用doGet(HttpServletRequest request , HttpServletResponse response) 如果是post请求,则调用doPost(HttpServletRequest request , HttpServletResponse response)
- 结论: 当通过继承HttpServlet来创建一个Servlet时,我们只需要根据要处理的请求的类型,来重写不同的方法。 处理get请求,则重写doGet() 处理post请求,则重写doPost()[6]
HttpServletRequest
代表:
浏览器发送给服务器的请求报文。
获取:
该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。 功能:
【1】获取用户发送的请求参数 request.getParameter("username"); 【2】获取项目的名字(用来设置绝对路径) request.getContextPath(); 【3】作为一个域对象,在不同的WEB资源之间共享数据。 【4】请求的转发 request.getRequestDispatcher("target.html").forward(request, response);
HttpServletResponse
代表: 服务器发送给浏览器的响应报文。 获取: 该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。 功能: 【1】响应给浏览器一个网页或者是网页片段(设置的是响应报文的响应体) response.getWriter(""); 【2】请求的重定向 response.sendRedirect("target.html")
转发和重定向:(掌握)
转发 重定向
请求的次数: 1 2
发生的位置 服务器内部 浏览器
浏览器地址栏 不改变 改变
浏览器的感知 不知道 知道
字符编码
> 当用户通过表单向Servlet发送中文请求参数时,Servlet获取到内容会产生乱码,
当Servlet向浏览器响应中文内容时,也会产生乱码。
> 浏览器和服务器之间通信时,中文内容时不能直接发送的,需要对中文进行编码。
> 编码:
- 将字符转换为二进制码的过程叫编码。
> 解码:
- 将二进制码转换为普通字符的过程叫解码。
> 编码和解码所采用的规则我们称为字符集。
> 产生乱码问题的根本原因:
编码和解码所采用的字符集不同。
> 解决方法:
统一编码和解码的字符集为UTF-8。
> 常见字符集:
1.ASCII
2.ISO8859-1
3.GBK
4.GB2312
5.UTF-8
> 请求编码
- 请求是浏览器发送给服务器的。
- 浏览器 --> 服务器
- 浏览器 编码
> 浏览器的会自动使用网页的字符集对参数进行编码
UTF-8的张三:%E5%BC%A0%E4%B8%89
GBK的张三:%D5%C5%C8%FD
> 所以我们只需要统一网页的字符集为UTF-8即可。
- 服务器 解码
post请求
> request解码时默认字符集时iso8859-1,但是iso压根就不支持中文
> post请求在servlet中解码,所以我们只需要指定request的字符集即可。
> 我们可以通过如下方法,来设置request的字符集:
request.setCharacterEncoding("utf-8");
> 注意:
该方法要在request.getParameter()第一次调用之前调用
get请求
> get请求是通过url地址传递请求参数,url中的请求参数将会被Tomcat服务器自动解码。
> Tomcat的默认编码是iso8859-1,但是iso压根就不支持中文,所以必然乱码。
> 只需要修改Tomcat的解码的默认字符集,修改配置文件server.xml
> 在server.xml的Connector标签中(改端口号的那个标签)添加如下属性:
URIEncoding="utf-8"
> 修改完配置文件以后,get请求的编码就不用再处理的,但是post请求还是老样子。
> 响应编码
- 响应是服务器发送给浏览器
- 服务器 --> 浏览器
- 服务器 编码
> 指定服务器的编码字符集为UTF-8。
> 指定response的字符集
response.setCharacterEncoding("utf-8");
> 虽然我们已经指定了response的字符集为utf-8,但是浏览器并不是用utf-8解码。
浏览器默认使用gb2312解码的,所以依然乱码,只不过没有那么乱。
- 浏览器 解码
> 浏览器的解码字符集可以通过浏览器来设置(不靠谱)
> 我们可以通过服务器来告诉浏览器,我们的内容的编码格式为utf-8
> 我们可以通过一个响应头来告诉浏览器,内容的编码格式:
Content-Type:text/html;charset=utf-8
> 通过response的方法,来设置响应头:
response.setHeader("Content-Type", "text/html;charset=utf-8");
解决方案:
1.设置响应头
response.setHeader("Content-Type", "text/html;charset=utf-8");
2.设置response的编码格式
response.setCharacterEncoding("utf-8");
> 当我们设置Content-Type这个响应头时,服务器会自动使用响应头中的字符集为内容编码。
> 最终方案:
response.setContentType("text/html;charset=utf-8");
总结: post请求: - 在request.getParameter()方法第一次调用之前,调用如下代码: request.setCharacterEncoding("utf-8"); get请求: - 修改server.xml配置文件
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
响应:
- 设置一个Content-Type响应头
response.setContentType("text/html;charset=utf-8");
路径问题
> URI和URL
- URL是URI的一种实现,也是URI最常见的实现方式。
- URI有两种实现方式URL和URN,URN用的很少
- 我们说URL和URI实际上可以理解为一个意思
> URL地址的格式
http://主机名:端口号/项目名/资源路径/资源名
①相对路径和绝对路径
> 相对路径
- 之前我们使用的路径全都是相对路径:
- 所谓的相对路径指相对于当前资源所在路径:
http://主机名:端口号/项目名/资源路径/
- 由于转发的出现,相对路径会经常发生变化,容易出现错误的链接
所以在开发中我们一般不使用相对路径,而是使用绝对路径。
> 绝对路径
- 绝对路径使用/开头
- 由浏览器解析的绝对路径中的/代表的是服务器的根目录:
http://主机名:端口号/
注意:需要加上项目名
- 由服务器解析的绝对路径中的/代表的项目的根目录:
http://主机名:端口号/项目名/
注意:不要加项目名
- 转发的路径由服务器解析,设置绝对路径时不需要加项目名
- 重定向的路径由浏览器解析,设置绝对路径时需要加上项目名
②常见的路径:
url-pattern:
转发的路径:
- url-pattern和转发中的路径都是由服务器解析的,
根目录是项目的根目录:
http://主机名:端口号/项目名/
- 所以这两个路径不需要加项目名
重定向的路径:
页面中的路径:
- 重定向和页面中的路径(HTML标签中的路径),由浏览器解析的,
根目录是服务器的根目录:
http://主机名:端口号/
- 所以这个两个路径必须加上项目名
(拓展)浅析Servlet执行原理
在JavaWeb学习研究中,Servlet扮演重要的作用,学好它,是后续JavaWeb学习的良好基础。无论是SSH,还是SSM,微服务JavaWeb技术,都应先学好Servlet,从而达到事半功倍的效果,本篇将主要分析Servlet的运行原理。
一、 UML
下图为Servlet UML关系图。
从图中,可以看出:
- 抽象类HttpServlet继承抽象类GenericServlet,其有两个比较关键的方法,doGet()和doPost()
- GenericServlet实现接口Servlet,ServletConfig,Serializable
- MyServlet(用户自定义Servlet类)继承HttpServlet,重写抽象类HttpServlet的doGet()和doPost()方法
注:任何一个用户自定义Servlet,只需重写抽象类HttpServlet的doPost()和doGet()即可,如上图的MyServlet
二、 Servlet在容器中的执行过程
Servlet只有放在容器中,方可执行,且Servlet容器种类较多,如Tomcat,WebLogic等。下图为简单的 请求响应 模型。
分析:
- 浏览器向服务器发出GET请求(请求服务器ServletA)
- 服务器上的容器逻辑接收到该url,根据该url判断为Servlet请求,此时容器逻辑将产生两个对象:请求对象(HttpServletRequest)和响应对象(HttpServletResponce)
- 容器逻辑根据url找到目标Servlet(本示例目标Servlet为ServletA),且创建一个线程A
- 容器逻辑将刚才创建的请求对象和响应对象传递给线程A
- 容器逻辑调用Servlet的service()方法
- service()方法根据请求类型(本示例为GET请求)调用doGet()(本示例调用doGet())或doPost()方法
- doGet()执行完后,将结果返回给容器逻辑
- 线程A被销毁或被放在线程池中
注意:
- 在容器中的每个Servlet原则上只有一个实例
- 每个请求对应一个线程
- 多个线程可作用于同一个Servlet(这是造成Servlet线程不安全的根本原因)
- 每个线程一旦执行完任务,就被销毁或放在线程池中等待回收
三、 Servlet在JavaWeb中扮演的角色
Servlet在JavaWeb中,扮演两个角色:页面角色和控制器角色。
有了jsp等动态页面技术后,Servlet更侧重于控制器角色,jsp+servlert+model 形成基本的三层架构
(一)页面Page角色
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("Hello!Servlet.");
}
(二)控制器角色
jsp充当页面角色,Servlet扮演控制器角色,两者组合构建基本的MVC三层架构模式
四 、Servlet在容器中的生命周期
下图为Servlet生命周期简要概图
分析:
第一步:容器先加载Servlet类
第二步:容器实例化Servlet(Servlet无参构造函数执行)
第三步:执行init()方法(在Servlet生命周期中,只执行一次,且在service()方法执行前执行)
第四步:执行service()方法,处理客户请求,doPost()或doGet()
第五步:执行destroy(),销毁线程
如果文章有错的地方欢迎指正,大家在评论区互相交流。
相关推荐
- 史上最全的浏览器兼容性问题和解决方案
-
微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...
-
- 平面设计基础知识_平面设计基础知识实验收获与总结
-
CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...
-
2025-02-21 16:01 yuyutoo
- 写作排版简单三步就行-工具篇_作文排版模板
-
和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...
- 写一个2048的游戏_2048小游戏功能实现
-
1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...
- 今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……
-
最近的天气暖和得让很多小伙伴们喊“热”!!! 昨天的气温到底升得有多高呢?你家有没有榜上有名?...
- CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式
-
之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...
- 你的自我界限够强大吗?_你的自我界限够强大吗英文
-
我的结果:A、该设立新的界限...
- 行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?
-
行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...
-
- 让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
-
去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...
-
2025-02-21 16:00 yuyutoo
- 今年国家综合性消防救援队伍计划招录消防员15000名
-
记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...
- 一起盘点最新 Chrome v133 的5大主流特性 ?
-
1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...
- 竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使
-
style="text-align:center;"data-mce-style="text-align:...
- 学物理能做什么?_学物理能做什么 卢昌海
-
作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...
-
- 你不知道的关于这只眯眼兔的6个小秘密
-
在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...
-
2025-02-21 16:00 yuyutoo
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)