简略来说:
servlet 是在服务器上运行的小程序。Servlet 的次要性能在于交互式地浏览和批改数据,生成动静 Web 内容,是为 web 开发服务的。
CGI 与 Servlet 比照
开始的时候,公共网关接口(CommonGateway Interface,CGI)脚本是生成动静内容的次要技术。尽管应用得十分宽泛,但 CGI 脚本技术有很多的缺点,这包含平台相关性和不足可扩展性。为了防止这些局限性,JavaServlet 技术因应而生,它可能以一种可移植的办法来提供动静的、面向用户的内容。解决用户申请。
比照一:当用户浏览器收回一个 Http/CGI 的申请,或者说调用一个 CGI 程序的时候,服务器端就要新启用一个过程(而且是每次都要调用),调用 CGI 程序越多(特地是访问量高的时候),就要耗费零碎越多的解决工夫,只剩下越来越少的系统资源,对于用户来说,只能是漫长的期待服务器端的返回页面了,这对于电子商务强烈倒退的明天来说,不能不说是一种技术上的遗憾。
而 Servlet 充分发挥了服务器端的资源并高效的利用。每次调用 Servlet 时并不是新启用一个过程,而是在一个 Web 服务器的过程中共享和拆散线程,而线程最大的益处在于能够共享一个数据源,使系统资源被无效利用。故 servlet 不是线程平安的,单实例多线程的
比照二:传统的 CGI 程序,不具备平台无关性特色,零碎环境发生变化,CGI 程序就要瘫痪,而 Servlet 具备 Java 的平台无关性,在零碎开发过程中放弃了零碎的可扩展性、高效性。
比照三:传统技术中,个别大都为二层的零碎架构,即 Web 服务器 + 数据库服务器,导致网站访问量大的时候,无奈克服 CGI 程序与数据库建设连贯时速度慢的瓶颈,从而死机、数据库死锁景象频繁产生。而咱们的 Servlet 有连接池的概念,它能够利用多线程的长处,在零碎缓存中当时建设好若干与数据库的连贯,到时候若想和数据库打交道能够随时跟零碎 ” 要 ” 一个连贯即可,反应速度可想而知。
Servlet 的运行过程
⒈ 客户端发送申请至服务器端;
⒉服务器端依据 web.xml 文件中的 Servlet 相干配置信息,将客户端申请转发到相应的 Servlet
⒊ Servlet 引擎调用 Service()办法,依据 request 对象中封装的用户申请与数据库进行交互,返回数据之后,Servlet 会将返回的数据封装到 response 对象中;
⒋ Servlet 生成响应内容并将其传给服务器。响应内容动静生成,通常取决于客户端的申请
⒌ 服务器将响应返回给客户端
Servlet 生命周期
1)加载和实例化;在第一次申请 Servlet 时,Servlet 容器将会创立 Servlet 实例;
2)初始化;Servlet 容器加载实现 Servlet 之后,必须进行初始化,此时,init 办法将被调用;
3)Servlet 初始化之后,就处于响应申请的就绪状态,此时如有客户端申请发送,就会调用 Servlet 实例的 service()办法,并且依据用户的申请形式,调用 doPost 或者 doGet 办法;
4)最初,Servlet 容器负责将 Servlet 实例进行销毁,调用 destroy 办法实现;
对于更多的客户端申请,Server 创立新的申请和响应对象,稀万代理 acy-ib.com 依然激活此 Servlet 的 service()办法,将这两个对象作为参数传递给它。如此反复以上的循环,但无需再次调用 init()办法。
个别 Servlet 只初始化一次 (只有一个对象), 当 Server 不再须要 Servlet 时(个别当 Server 敞开时),Server 调用 Servlet 的 Destroy() 办法。
实例解析:
html 代码 – 客户端浏览器
<span style=”font-family:KaiTi_GB2312;”><html>
<head>
<title> 学生治理 </title>
</head>
<body>
<h1> 依据出生日期段查问 </h1>
<form action="queryStudentServlet">
出生日期:<input type="text" name="beginDate"> 至 <input type="text" name="endDate">
<input type="submit" value="查问学生">
</form>
</body>
</html>
</span>
配置文件
<span style=”font-family:KaiTi_GB2312;”><servlet>
<servlet-name>StudentMgrServlet</servlet-name>
<servlet-class>StudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentMgrServlet</servlet-name>
<url-pattern>/queryStudentServlet</url-pattern>
</servlet-mapping>
</span>
servlet 处理过程
<span style=”font-family:KaiTi_GB2312;”> import java.text.*;
import java.util.*;
import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;
import com.bjpowernode.exam.model.*;
import com.bjpowernode.exam.manager.*;
public class StudentServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {String sBeginDate = request.getParameter("beginDate");
String sEndDate = request.getParameter("endDate");
Date beginDate = new Date();
Date endDate = new Date();
try {beginDate = new SimpleDateFormat("yyyy-MM-dd").parse(sBeginDate);
endDate = new SimpleDateFormat("yyyy-MM-dd").parse(sEndDate);
}catch(Exception e) {e.printStackTrace();
}
StudentManager studentManager = new StudentManagerImpl();
List<Student> studentList = studentManager.findStudentList(beginDate, endDate);
// 表格省略…
}
}
</span>
Servlet 如何同时解决多个申请?
Servlet 采纳多线程来解决多个申请的同时拜访。Servlet 容器通过线程池来治理保护服务申请。所谓线程池,相当于数据库连接池,实际上是期待执行代码的一组线程,叫做工作者线程。Servlet 容器通过一个调度线程来治理工作者线程。
· 当容器收到一个 Servlet 的拜访申请,调度者线程就从线程池中选出一个工作者线程,将用户申请传递给该线程,而后由该线程解决 Servlet 的 service()办法;
· 当这个线程在执行的时候,容器收到一个新的申请,调度者线程再次从线程池中选出一个新的工作者线程;
· 当容器同时收到对同一个 Servlet 的多个申请时,那么 Servlet 的 service 办法将在多线程中并发执行。
注:
1.Servlet 容器默认采纳单实例多线程的形式来解决申请。这样缩小了产生 Servlet 实例的开销,晋升了对申请的响应工夫;
2. 对于 Tomcat 容器来讲,能够在其 server.xml 中通过 <Connector> 中设置线程池中的线程数目。
如何开发线程平安的 Servlet?
Servlet 容器采纳多线程来解决申请,进步性能的同时也造成了线程平安问题。要开发线程平安的 Servlet 应该从一下几个方面进行:
1. 变量的线程平安;多线程并不共享局部变量,所以咱们要尽可能的在 Servlet 中应用局部变量;
2. 代码块的线程平安;应用同步块 Synchronized,避免可能调用的代码块;然而要留神的是,要尽可能得放大同步代码的方范畴,不要在 service 办法和响应办法上间接应用同步,这会重大影响性能。
3. 属性的线程平安;ServletContext,HttpSession,ServletRequest 对象中属性;
4. 应用同步汇合;应用 Vector 代替 ArrayList,应用 HashTable 代替 HashMap;
5. 不要在 Servlet 中创立本人的线程来实现某个性能;Servlet 自身就是多线程的,如果再创立新的线程,将会导致线程执行复杂化,呈现线程平安问题;
6. 在多个 Servlet 中,对外部对象,比方:文件;进行批改操作肯定要加锁,做到互斥拜访;
总结:
一个 servlet 就是 Java 编程语言中的一个类,它被用来扩大服务器的性能,服务器上驻留着能够通过“申请 - 响应”编程模型来拜访的应用程序。Servlet 通过解析 http 申请,获得客户端的参数来进行下一步操作。其实简略来说,servlet 就是一个控制器,取参数,调用业务逻辑.
而在.net 中 HttpHandler 是一个 HTTP 申请的真正解决核心,也正是在这个 HttpHandler 容器中,ASP.NET Framework 才真正地对客户端申请的服务器页面做出编译和执行,并将解决过后的信息附加在 HTTP 申请信息流中再次返回到 HttpModule 中。