什么是Servlet?
1.Servlet
是一种独立于平台和协议的服务端的java技术,可以生成动态WEB页面与传统的CGI(计算机图形接口)和其他类似的CGI技术相比。Servlet具有更好的可移植性。更强大的功能,更少的投资,更高的效率,更好的安全性。
2.Servlet
是使用java Servlet应用程序接口(API)及相关类和方法的java程序。java语言能够实现的功能Servlet基本都能够实现。(除了图形化界面)。Servlet 主要用于处理客户端传来的Http 请求,并返回一个响应,通常来说Servlet就是指HttpServlet,用于处理Http请求,其能够处理的请求有doGet(),doPost(),service()等方法,开发servlet时可以直接结成javax.servlet,http.HttpServlet.
3.Servlet
需要在web.xml中进行描述,例如。映射执行servlet的名字,配置servlet类,初始化参数,进行安全配置,URL映射和设置启动优先权。Servlet不仅可以生成HTML脚本输出,也可以生成二进制表单输出。
4.Servlet
应用广泛,现在许多流行框架都离不开Servlet的支持,比如SHH,Spring 容器启动的时候,要在web,xml中装载Spring容器和Actioncontext来初始化Spring的一些参数。如依赖注入,数据库表的映射,初始化系统的安全配置设置read等属性进行一些相关的操作。
Servlet 的生命周期
**Servlet **被服务器实例化
后,容器运行其
init 方法,请求到达时运行其
service 方法,service 方法自动派遣运行与请求对应的
doXXX 方法(doGet,doPost)等,当服务器决定将实例 销毁的时候调用其
destroy 方法。web 容器加载 servlet,生命周期开始。通过调用 servlet 的 init()方法进行 servlet 的初始化。 通过调用 service()方法实现,根据请求的不同调用不同的 do***()方法。结束服务,web 容 器调用 servlet 的 destroy()方法。
Servlet 的基本架构
public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
}
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
}
}
Servlet API 中 forward()与 redirect()的区别?
怎样理解Servlet的单实例多线程?
不同的用户同时对同一个业务(如注册)发出请求,那这个时候容器里产生的有是几个servlet实例呢?
答案是:
只有一个servlet实例。一个servlet是在第一次被访问时加载到内存并实例化的。同样的业务请求共享一个servlet实例。不同的业务请求一般对应不同的servlet。
由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全性问题。
JSP的中存在的多线程问题:
当客户端第一次请求某一个JSP文件时,服务端把该JSP编译成一个CLASS文件,并创建一个该类的实例,然后创建
一个线程处理CLIENT端的请求。如果有
多个客户端同时请求该JSP文件,则服务端会创建
多个线程。每个客户端请求对应一个线程。以多线程方式执行可
大大降低对系统的资源需求,
提高系统的并发量及响应时间。
对JSP中可能用的的变量说明如下:
实例变量:
实例变量是在堆中分配的,并被属于该实例的所有线程共享,所以
不是线程安全的。
JSP系统提供的8个类变量
JSP中用到的
out,request,response,session,config,page,pageContext是
线程安全的(因为每个线程对应的request,respone对象都是不一样的,不存在共享问题),
APPLICATION在整个系统内被使用,所以
不是线程安全的。
局部变量:
局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是
线程安全的。
静态类:
静态类不用被实例化,就可直接使用,也
不是线程安全的.
外部资源:
在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).此时也要
注意同步问题.
Servlet单实例多线程机制:
Servlet
采用多线程来处理多个请求同时访问。servlet依赖于一个线程池来服务请求。
线程池实际上是一系列的
工作者线程集合。Servlet使用
一个调度线程来管理工作者线程。
当容器收到
一个Servlet请求,
调度线程从
线程池中选出一个
工作者线程,将请求传递给该
工作者线程,然后由该线程来
执行Servlet的service方法。当这个线程正在执行的时候,容器收到
另外一个请求,调度线程同样从线程池中选出
另一个工作者线程来服务新的请求,容器并
不关心这个
请求是否访问的是
同一个Servlet.当
容器同时
收到对
同一个Servlet的
多个请求的时候,那么这个Servlet的service()方法将在
多线程中并发执行。
Servlet容器默认采用
单实例多线程的方式来处理请求,这样
减少产生Servlet实例的
开销,
提升了对请求的
响应时间,对于
Tomcat可以在
server.xml中通过
<Connector>元素设置线程池中
线程的数目。
如何开发线程安全的Servlet?
1、实现
SingleThreadModel 接口
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为:
Public class Concurrent Test extends HttpServlet implements SingleThreadModel {
…………
}
2、同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段
3、避免使用实例变量
只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。
备注:
1)
Struts2的Action是
原型,
非单实例的;会对每一个请求,产生一个Action的实例来处理。
2)
Struts1Action是
单实例的,
Spring mvc的controller也是如此。因此开发时
要求必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。
Action资源必须是
线程安全的或
同步的。
3)
** Struts1的Action,
Spring的Ioc**容器管理的bean
默认是
单实例的.
4)
Struts2Action对象为
每一个请求产生一个实例,因此
没有线程安全问题。(实际上,
servlet容器给
每个请求产生许多
可丢弃的
对象,并且
不会导致性能和垃圾回收问题)。
5)当
Spring管理Struts2的Action时,
bean默认是单实例的,可以
通过配置参数将其
设置为原型。(scope="prototype )
servlet与jsp的区别
1.
jsp经
编译后就
变成了
Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
2.
jsp更擅长表现于
页面显示,
servlet更擅长于
逻辑控制.
3.
Servlet中
没有内置对象,
内置对象都是
必须通过
HttpServletRequest对象,
HttpServletResponse对象以及
HttpServlet对象
得到.
Jsp是
Servlet的一种
简化,使用Jsp只需要完成程序员需要输出到客户端的内容,
Jsp中的
Java脚本如何
镶嵌到一个
类中,由
Jsp容器完成。而
Servlet则
是个
完整的Java类,这个类的
Service方法用于
生成对客户端的
响应。
4.对于
静态HTML标签,
Servlet都
必须使
用页面
输出流逐行输出.
网友评论