初窥Servlet

1. Servlet简介

        Servlet是sun公司提供的一门用于开发动态web资源的技术。sun公司在其API中提供了一个servlet接口,用户若想要发一个动态web资源,只需要完成以下两步即可:

           1)编写一个servlet,即实现servlet接口的Java类;

           2) 把开发好的servlet部署到web服务器中。

        Servlet接口定义了所有servlet必须实现的方法。一个servlet是运行在web服务器中的一个小java程序,servlet通过HTTP协议接收并响应web客户端发来的请求。这个接口中定义的方法包括初始化servlet,服务请求,以及remove servlet,这些方法即servlet的生命周期方法,调用顺序如下:

           1)某个创建servlet对象的时候,调用初始化方法: void init(ServletConfig config)

           2)客户端发送请求的时候,service方法被执行:void service(ServletRequest req, ServletResponse res)

           3)某个servlet对象被摧毁的时候,调用destroy方法: void destroy()

        除了这些与生命周期有关的方法外,Servlet接口还提供了getServletConfig方法和getServletInfo方法,getServletConfig方法可以获得servlet的一些启动信息,getServletInfo方法可以返回servlet本身的一些信息。

        sun公司定义了Servlet接口的两个默认实现类,分别为javax.servlet.GenericServlet和javax.servlet.http.HttpServlet。

        HttpServlet指能够处理HTTP请求的servlet,它再原有的Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大,因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法

2. Servlet的运行过程

        Servlet程序是由web服务器调用,web服务器接收到客户端的Servlet访问请求后:
           1)web服务器首先检查是否已经装载并创建了该Servlet的实例对象,如果是,则直接执行第4步,否则执行第2步。
           2)装载并创建该Servlet的一个实例对象。
           3)调用Servlet实例对象的init()方法。
           4)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP相应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
           5)web应用程序被停止或重新启动前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

3. Servlet的几个细节

1. Servlet细节1

        由于客户端是通过URL地址访问文本服务器中的资源,所以servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

       1) <servlet>元素用于注册Servlet,它包含两个主要的子元素:

              <servlet-name>:用于设置Servlet的注册名称

              <servlet-class>:用于设置Servlet的完整类名

        2)<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含两个子元素:

              <servlet-name>:用于设置Servlet的注册名称

              <url-pattern>:用于指定Servlet的对外访问路径(可以随便指定)

        例如:

<web-app>  <servlet>  <servlet-name>AnyName</servlet-name>  <servlet-class>HelloServlet</servlet-class>  </servlet>  <servlet-mapping>  <servlet-name>AnyName</servlet-name>  <url-pattern>/demo/hello.html</url-pattern>  </servlet-mapping>  
</web-app>  

2. Servlet细节2

        同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是:“*.扩展名”;另一种格式是:以“/”开头,并以“/*”结尾。例如:

<servlet-mapping>  <servlet-name>AnyName</servlet-name>  <url-pattern>*do</url-pattern>  
</servlet-mapping>  

 也可以映射到另一个url:

<servlet-mapping>  <servlet-name>AnyName</servlet-name>  <url-pattern>/action/*</url-pattern>  
</servlet-mapping>  

3. servlet细节3

        Servlet是一个供其他java程序(Servlet引擎)调用的java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才销毁。
        在Servlet的整个生命周期中,Servlet的init方法只被调用一次,而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doGet或doPost方法。

4. servlet细节4

        如果再<servlet>元素中配置了一个<load-on-startup>元素,那么web应用程序在启动时,就会装载并创建Servlet的实例对象,以及调用Servlet实例对象的init()方法。该技术可以用来为web写一个initServlet,这个servlet配置为启动时装载,为整个web应用床架必要的数据库表和数据。如:

<servlet>  <servlet-name>...</servlet-name>  <servlet-class>...</servlet-class>  <load-on-startup>1<load-on-startiup>  
</servlet>  

5. servlet细节5

        如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的url,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
        在<tomcat安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaulServlet的Servlet,并将这个Servlet设置为了缺省Servlet。当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。
        假设现在在工程名为test的WebRoot目录下新建一个1.html,在web.xml文件中并没有配置<servlet-mapping>,即在工程中没有Servlet映射成1.html,然后访问:http://localhost:8080/test/1.html时,这时候这个请求就交给缺省的Servlet,缺省的Servlet收到请求后,会首先看一下web应用下面有没有这个1.html,如果有则读取并返回到浏览器,如果没有则返回一个错误页面。

6. servlet细节6

        当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因为Servlet只有一个实例化对象,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。那么如何解决Servlet中的线程安全问题呢?
       1) 如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。该接口没有任何方法,它起到了一个标志的作用。对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线成并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立Servlet实例对象。

       2)使用synchronized 关键字,synchronized能保证一次只有一个线程可以访问被保护的区段,从而可以通过同步块操作来保证线程的安全。

       3)尽量避免在Servlet里使用实例变量,只要在Servlet里面的任何方法里面都不使用共有的实例变量,那么该Servlet就是线程安全的。

       以上三种方式中,实现SingleThreadModel接口可以解决问题,但是并不是真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。另外,创建多个Servlet实例对象也会引起大量的开销。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为过时的了。

        同样,如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。所以在实际的开发中也应避免或最小化 Servlet 中的同步代码。

        所以,在Servlet中避免使用实例变量是保证Servlet线程安全的最佳选择。

3. Servlet的Hello Word

        最后写一个再简单不过的Hello Word吧……

public class ServletDemo extends HttpServlet {  public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  System.out.println("Hello word!");  }  public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  doGet(request, response);  }  
}  

 web.xml:

<servlet>  <servlet-name>ServletDemo</servlet-name>  <servlet-class>servlet.ServletDemo</servlet-class>  <load-on-startup>1</load-on-startup>  
</servlet>  
<servlet-mapping>  <servlet-name>ServletDemo</servlet-name>  <url-pattern>/ServletDemo</url-pattern>  
</servlet-mapping>  

入门就这么多吧,如有错误之处,欢迎留言指正~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊接口性能优化的11个小技巧

前言 接口性能优化对于从事后端开发的同学来说&#xff0c;肯定再熟悉不过了&#xff0c;因为它是一个跟开发语言无关的公共问题。 该问题说简单也简单&#xff0c;说复杂也复杂。 有时候&#xff0c;只需加个索引就能解决问题。 有时候&#xff0c;需要做代码重构。 有时…

三元表达式,递归,匿名函数,内置函数

一 、三元表达式 只应用于条件成立返回一个值&#xff0c;条件不成立返回另一个值。   示例&#xff1a;    nameinput(姓名>>: )    resSB if name alex else NB    print(res) 注&#xff1a;通常使用场合为特别简单一眼读懂的地方。二…

ElasticSearch远程随意代码运行漏洞(CVE-2014-3120)分析

原理 这个漏洞实际上非常easy&#xff0c;ElasticSearch有脚本运行(scripting)的功能&#xff0c;能够非常方便地对查询出来的数据再加工处理。 ElasticSearch用的脚本引擎是MVEL&#xff0c;这个引擎没有做不论什么的防护&#xff0c;或者沙盒包装&#xff0c;所以直接能够运行…

《Effective Java》—— 对于所有对象都通用的方法

本节主要涉及Object中通用的一些方法&#xff0c;比如equals,hashCode,toString,clone,finalize等等 覆盖equals时请遵守通用约定 equals方法实现的等价关系&#xff1a; 自反性&#xff1a;对于所有的非null&#xff0c;aa对称性&#xff1a;ab,则ba传递性&#xff1a;ab,bc,则…

.net core实现读取自定义配置文件

背景在.net core类库中读取配置文件&#xff0c;正常来讲我们在应用程序目录下有个appsettings.json文件对于相关配置都会放在这个json文件中&#xff0c;但是要是建立一个类库项目&#xff0c;对于一些配置比如密钥或者其他需要硬编码的数据放在JSON文件中&#xff0c;在.net …

Java中ArrayList,LinkedList,Vector三者的异同点及其使用场景和ArrayList的一些常用方法

相同点&#xff1a;三者存储的都是有序&#xff0c;可重复的数据。 异&#xff1a; ①&#xff1a;ArrayList底层存储类型是Object数组&#xff0c;而LinkedList底层是双向链表 ②&#xff1a;ArrayList和Vector调用创建空参构造器创建对象时&#xff0c;默认的size是10&…

第二百四十六节,Bootstrap弹出框和警告框插件

Bootstrap弹出框和警告框插件 学习要点&#xff1a; 1.弹出框 2.警告框 本节课我们主要学习一下 Bootstrap 中的弹出框和警告框插件。 一&#xff0e;弹出框 弹出框即点击一个元素弹出一个包含标题和内容的容器。 基本用法 注意&#xff1a;必须在js结合popover()方法使用 da…

Intellij IDEA2017 的控制台里不识别maven命令问题处理

2019独角兽企业重金招聘Python工程师标准>>> cmd里运行 mvn -v可以显示出maven的版本信息&#xff0c;可是在IDEA的控制台里却提示不识别maven命令&#xff0c;此情况以管理员的身份运行IDEA即可。 转载于:https://my.oschina.net/u/2364025/blog/1788797

使用IDEA 提交代码到svn

2019独角兽企业重金招聘Python工程师标准>>> 新手第一次使用教程&#xff1a; 一、安装svn TortoiseSVN是个客户端&#xff0c;需要安装VisualSVN服务端。 二、IDEA配置&#xff08;Ctrl alt S&#xff09; 需要配置服务端svn.exe文件。 三、上传代码 svn路径&…

如何在 BackgroundService 获取 ASP.NET Core 启动地址

前言上次&#xff0c;我们介绍了《如何获取 ASP.NET Core 启动地址》。但是&#xff0c;如果要在 BackgroundService 中获取启动地址可不那么容易&#xff0c;因为 BackgroundService 在 app 启动前就开始执行了:var builder WebApplication.CreateBuilder(args); builder.Ser…

JDK8 循环遍历list

简介 Java 8 API添加了一个新的抽象称为流Stream&#xff0c;可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。 这种风格将要处理的元素集合看作一种流&#xff0c; 流在管道中传输&…

2016 校园招聘求职经历(二)

概述 航信是一家国企&#xff0c;给人的印象是比较踏实&#xff0c;不过也感觉缺乏活跃性。我是航信第一批校招去&#xff0c;同样它也是我面试的第一家公司。 宣讲会 9月27日&#xff0c;下午2&#xff1a;30开始宣讲会&#xff0c;大约持续了30分钟左右&#xff0c;整个感觉是…

016-Spring Boot JDBC

一、数据源装配 通过查看代码可知&#xff0c;默认已装配了数据源和JdbcTemplate System.out.println(context.getBean(DataSource.class)); System.out.println(context.getBean(JdbcTemplate.class)); 1.1、环境搭建 主要是pom引用&#xff1a;spring-boot-starter-jdbc、增加…

分库分表和 NewSQL 到底怎么选?

文章来源&#xff1a;【公众号&#xff1a;CoderW】 目录 背景 分表 分库 分库分表的成本 NewSQL NewSQL 平滑接入方案 NewSQL 真的有那么好吗&#xff1f; NewSQL 的应用 分库分表和 NewSQL 到底怎么选&#xff1f; 背景 曾几何时&#xff0c;“并发高就分库&#xff…

JsonPath基本使用

概述在.Net开发中&#xff0c;一般操作Json都是使用Newtonsoft.Json包&#xff0c;下面我们来使用该包以类似xpath的方式JsonPath操作Json。介绍JsonPath是xpath在json中的应用&#xff0c;是参照xpath表达式来解析xml文档的方式&#xff0c;用一个抽象的名字$来表示最外层的对…

jQuery/javascript实现简单网页计算器

1 <html>2 <head>3 <meta charset"utf-8">4 <title>jQuery实现</title>5 <script src"jquery.js"></script>6 7 <style type"text/css">8 table{background-color:pink;width:300px;height…

AC日记——Paint Pearls hdu 5009

Paint Pearls 思路&#xff1a; 离散化dp剪枝&#xff1b; dp是个n方的做法&#xff1b; 重要就在剪枝&#xff1b; 如果一个长度为n的区间&#xff0c;有大于根号n种颜色&#xff0c;还不如一个一个涂&#xff1b; 来&#xff0c;上代码&#xff1a; #include <cstdio> …

CSS缩写总结

1、16进制的色彩值&#xff0c;如果每两位的值相同&#xff0c;可以缩写一半。如&#xff1a; color: #ffffff > color: #fffcolor: #aabbcc > color: #abc2、边框语法糖 边框&#xff1a; border: width style color; > border: (边宽) (样式) (颜色); 如&#xff1a…

雷军招人反被3句话问懵:当我在面试牛人的时候,牛人也在面试我

来 源&#xff5c;环球人力资源智库&#xff08;GHRlib&#xff09; 作 者&#xff5c;Black “你做过手机吗&#xff1f;” “没做过。” “你认识中移动老总王建宙吗&#xff1f;” “不认识。” “你认识富士康老板郭台铭吗&#xff1f;” “我认识他&#xff0c;他不认识我…

【jQuery系列之插件】jQuery插件---exselect实现联动

<!DOCTYPE HTML> <html> <head><meta charset"utf-8"><title>cxSelect 联动下拉菜单 </title><style>body{background:#ddd;font:14px/1.7 tahoma,\5fae\8f6f\96c5\9ed1,sans-serif;}fieldset{margin:2em 0;}fieldset leg…