原文链接:http://blog.csdn.net/eson_15/article/details/51245629
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方法。
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()方法。
由于客户端是通过URL地址访问文本服务器中的资源,所以servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用
1)
2)
例如:
AnyName
HelloServlet
AnyName
/demo/hello.html
同一个Servlet可以被映射到多个URL上,即多个
AnyName
*do
也可以映射到另一个url:
AnyName
/action/*
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方法。
如果再
...
...
1
如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。凡是在web.xml文件中找不到匹配的
在
假设现在在工程名为test的WebRoot目录下新建一个1.html,在web.xml文件中并没有配置
当多个客户端并发访问同一个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 中的同步代码。
所以,在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。
最后写一个再简单不过的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:
ServletDemo
servlet.ServletDemo
1
ServletDemo
/ServletDemo
入门就这么多吧,如有错误之处,欢迎留言指正~
_____________________________________________________________________________________________________________________________________________________
—–乐于分享,共同进步!