JavaWed_Servlet

一、Servlet概述

1.sun公司提供的动态web资源开发技术。本质是上一段java小程序,要求这个小程序必须实现Servlet接口,以便服务器能够调用。


2.开发Servlet的两个步骤


*实验:Servlet的快速入门
(1)步骤一:写一个java程序实现Servlet接口(此处直接继承了默认实现类GenericServlet)
package cn.itheima;
import java.io.*;
import javax.servlet.*;

public class FirstServlet extends GenericServlet{
public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException{
res.getOutputStream().write("My FirstServlet!".getBytes());
}

}

(2)将编译好的带包的.class放到WEB-INF/classes下以外,还要配置web应用的 web.xml注册Servlet
               <servlet>
                        <servlet-name>FirstServlet</servlet-name>
                        <servlet-class>cn.itheima.FirstServlet</servlet-class>
                </servlet>
                <servlet-mapping>
                <servlet-name>FirstServlet</servlet-name>
                <url-pattern>/FirstServlet</url-pattern>

                </servlet-mapping>


3.利用MyEclipse开发Servlet
 

二、Servlet的详述


1.生命周期:一件事物什么时候生,什么时候死,在生存期间必然会做的事情,所有这些放在一起就是该事物的声明周期。


2.Servlet的生命周期:通常情况下,servlet第一次被访问的时候在内存中创建对象,在创建后立即调用init()方法进行初始化。对于每一次请求都掉用service(req,resp)方法处理请求,此时会用Request对象封装请求信息,并用Response对象(最初是空的)代表响应消息,传入到service方法里供使用。当service方法处理完成后,返回服务器服务器根据Response中的信息组织称响应消息返回给浏览器。响应结束后servlet并不销毁,一直驻留在内存中等待下一次请求。直到服务器关闭或web应用被移除出虚拟主机,servlet对象销毁并在销毁前调用destroy()方法做一些善后的事情。


3.Servlet接口的继承结构
Servlet接口:定义了一个servlet应该具有的方法,所有的Servlet都应该直接或间接实现此接口
                    |
                    |----GenericServlet:对Servlet接口的默认实现,通用Servlet,这是一个抽象类,其中的大部分方法都做了默认实现,只有service方法是一个抽象方法需要继承者自己实现
                                                     |
                                                     |----HttpServlet:对HTTP协议进行了优化的Servlet,继承自GenericServlet类,并且实现了其中的service抽象方法,默认的实现中判断了请求的请求方式,并根据请求方式的不同分别调用不同的doXXX()方法。通常我们直接继承HttpServlet即可



4.web.xml注册Servlet的注意事项


           4.1利用<servlet><servlet-mapping>标签注册一个Servlet
                   <servlet>
                <servlet-name>FirstServlet</servlet-name>
                <servlet-class>cn.itheima.FirstServlet</servlet-class>  注意:此处要的是一个Servlet的完整类名,不是包含.java或.class扩展的文件路径
               </servlet>
               <servlet-mapping>
               <servlet-name>FirstServlet</servlet-name>
               <url-pattern>/FirstServlet</url-pattern>

               </servlet-mapping>


           4.2一个<servlet>可以对应多个<servlet-mapping>


           4.3可以用*匹配符配置<serlvet-mapping>,但是要注意,必须是*.do或者/开头的以/*结束的路径。

          ~由于匹配符的引入有可能一个虚拟路径会对应多个servlet-mapping,此时哪个最像找哪个servlet,并且*.do级别最低。


           4.4可以为<servlet>配置<load-on-startup>子标签,指定servlet随着服务器的启动而加载,其中配置的数值指定启动的顺序
                 <servlet>
                   <servlet-name>invoker</servlet-name>
                   <servlet-class>
                       org.apache.catalina.servlets.InvokerServlet
                    </servlet-class>
                  <load-on-startup>2</load-on-startup>

                 </servlet>


          4.5缺省servlet:如果一个servlet的对外访问路径被设置为/,则该servlet就是一个缺省servlet,其他servlet不处理的请求都由它来处理

                ~在conf/web.xml中配置了缺省servlet,对静态资源的访问和错误页面的输出就是由这个缺省servlet来处理的。如果我们自己写一个缺省servlet把web.xml中的缺省servlet覆盖的话,会导致静态web资源无法访问。所以不推荐配置。


          4.6servlet的线程安全问题
                       4.6.1由于通常情况下,一个servlet在内存只有一个实例处理请求,当多个请求发送过来的时候就会有多个线程操作该servlet对象,此时可能导致线程安全问             题。
                            (1)serlvet的成员变量可能存在线程安全问题
                                 *实验:定义一个成员变量 int i = 0;在doXXX()方法中进行i++操作并输出i值到客户端,此时由于延迟可能导致线程安全问题
                            (2)serlvet操作资源文件时,多个线程操作同一文件引发线程安全问题
                                 *实验:请求带着一个参数过来,servlet将请求参数写入到一个文件,再读取该文件,将读取到的值打印到客户端上,有可能有线程安全问题

                      4.6.2解决方法
                           (1)利用同步代码块解决问题。缺陷是,同一时间同步代码块只能处理一个 请求,效率很低下,所以同步代码块中尽量只包含核心的导致线程安全问题的代码。
                           (2)为该servlet实现SingleThreadModel接口,此为一个标记接口,被标记的servlet将会在内存中保存一个servlet池,如果一个线程来了而池中没有servlet对象处理,则创建一个新的。如果池中有空闲的servlet则直接使用。这并不能真的解决线程安全问题。此接口已经被废弃。
                           (3)两种解决方案都不够完美,所以尽量不要在servlet中出现成员变量。

你可能感兴趣的:(JavaWed_Servlet)