一、Servlet简介
Servlet是Sun公司提供的一门基于Java语言开发动态Web资源的技术。
Web资源技术,本人的理解是。是类似于JavaScript的脚本语言、php等。
Servlet的本质是,java类实现了库中的Servlet接口,(HttpServlet接口)。
根据页面http(客户端)发送的Request请求,通过Response响应,编辑响应头和响应方法,实现Web资源动态管理。
二、Servlet主要实现的方法:
Servlet接口类主要的两个方法类:GenericServlet类、HttpServlet类。
HttpServlet在Servlet的方法类上覆写了它的方法、它基于Servlet,但比servlet接口更强大。所以在开发的时候,
普遍使用HttpServlet、而避免直接使用Servlet。在HttpServlet中,用doGet和doPost方法,作为Request响应客户端的请求。
三、Servlet的映射
客户端访问Servlet服务端的时候是通过URL地址访问Web服务器中的资源,所以必须把Servlet映射到一个Url上。
servlet的地址在web.xml中,用<servlet>元素(注册Servlet)和<servlet-mapping>(映射已注册的Servlet对外访问路径)元素完成。
<servlet>有两个子元素<servlet-name>和<servlet-class>。分别用于设置Servlet的注册名称和Servlet的完整类名。
<servlet-mapping>有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。
四、Servlet有别于普通Java类
servlet是java中的一个类。用于拓展服务器的性能,服务器上驻留,可以通过“请求-响应”编程模式
Servlet是一个供其他java程序调用的java类,它不能独立运行,它的运行完全由servlet引擎控制和调度。
针对客户端的多次servlet请求,服务器只会创建一个servlet实例对象。在它的生命周期中,创建之后就会保留在内存当中,为后续的
其他请求服务。init()方法只会调用一次,而当web容器推出servlet时候,才会调用destory()方法,销毁对象。
对每一个Servlet的访问都会导致引擎调用servlet的service方法,对于每次的访问请求,都会创建一个httpservletrequest请求对象和
httpservletresponse响应对象。然后这两个对象作为参数传递给servlet的service()方法。servlet方法再根据请求方式调用doget或
dopost方法。虽然servlet可以对任何类型的请求产生相应,但通常只用来拓展Web服务器的应用程序。Java Servlet技术为这些应用
定义了一个特定的于Http的 Serlvet类。
五、多个客户端同时访问一个Servlet引发了线程问题
问题原因:
Servlet本身是单实例的。当多个用户同时访问某个servlet时候,会访问该唯一的Servlet实例中的成员变量,如果成员变量进行写入
操作,会导致servlet的多线程问题,即数据不一致。
解决同步方法:
1.解决servlet的最好方法:
去除实例变量,使用局部变量。
对于servlet而言,不使用成员变量,而使用局部变量,因为局部变量在每个线程中都有各自的实例。
2.sun公司提出的解决方法:
让servlet去实现一个SingleThreadModel的接口,当某个Servlet实现了SingeThreadModel接口,那么Servlet引擎将以单线程模式来调用其Service方法。
而SingeThreadModel接口中。没有任何的方法和常量。在JAVA中把没有定义任何方法和常量的接口称为标记接口。让Servlet实现了SingeThreadModel接口,只要在Servlet类中的定义中增加实现SingeThreadModel接口的声明即可。
对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。
实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。