Servlet实质上是一个java类,只不过这个类需要符合一些规范。它必须实现java.servlet.Servlet接口的所有方法,提供一个无参的构造方法。它只能在web容器中存活,在java Web服务器中充当了信息资源的最小表示单位,代表了一个用户可以通过浏览器获取的资源。在架构设计上,servlet层用来完成页面逻辑,包括参数获取,页面跳转。Servlet可以无限制的扩展,它可以使用java的所有类库的资源,为用户返回各种资源信息。
关于Servelet的工作原理,我们可以从它的生命周期入手,Servlet的生命周期分四个阶段:类装载及实例创建阶段、实例初始化阶段、服务阶段、实例销毁阶段。在web服务器中如下:
tomcat启动 tomcat关闭
加载Servlet类、进驻内存、调用init()方法初始化、服务阶段、调用destroy()方法注销
默认情况下,Servlet实例是在接受到第一个请求时进行创建并且以后的请求进行复用,如果有Servlet实例需要进行一些复杂的操作,需要在初始化时就完成,比如打开文件、初始化网络连接等,可以配置在服务器启动时就创建实例,具体配置方法为在声明servlet标签中添加<load-on-startup>1</load-on-startup>标签(<load-on-startup>0</load-on-startup>则表示初始化时才创建实例)。初始化 init(ServletConfig config)
一旦Servlet实例被创建,将会调用Servlet的inint方法,同时传入ServletConfig实例,传入Servlet的相关配置信息,init方法在整个Servlet生命周期中只会调用一次。
为了提高效率,Servlet规范要求一个Servlet实例必须能够同时服务于多个客户端请求,即service()方法运行在多线程的环境下,Servlet开发者必须保证该方法的线程安全性。
当Servlet容器将决定结束某个Servlet时,将会调用destory()方法,在destory方法中进行资源释放,一旦destory方法被调用,Servlet容器
将不会再发送任何请求给这个实例,若Servlet容器需再次使用该Servlet,需重新再实例化该Servlet实例。
在实际开发中,我们往往通过继承自javax.servlet.httpServlet来创建,它可以为我们提供一些方法的默认实现,还可以区别不同的请求方法(Get和Post)。Get和Post都是页面请求的方式,二者又有一些不同:Post是通过Http中的Post机制将表单中的数据提交道Action所制定的程序,Get方法是通过Url请求来提交表单数据的;Get适用于传输数据量小于1K数据,执行效率高;Post传输数据量较大,但也有限量。
Servlet实现页面跳转有三种方式:response.sendRedirect("url")、request.getRequestDispatcher("url").forword(request,response)和out.println("<script>window.location.href = "url"</script>");
response.sendRedirect("url")和request.getRequestDispatcher("url").forword(request,response)这两种方法都能实现页面的跳转,但是他们两者的本质是不一样的。
response.sendRedirect("url")是重定向,当一个Servlet向当前的Servlet发出请求后,经过当前的Servlet的方法后,会再向服务器发出一个请求,生定向到这个方法中指定的URL,也就是说,在这个过程中,Servlet要向服务器请求两次,才能转到请求的URL。这种方式跳转后,以前的request中存放的变量全部失效,进入一个新的request区。
request.getRequestDispatcher("url").forword(request,response)是请求转发,也就是说,一个Servlet向当前的Servlet发出请求后,经过这个方法后,请求会继续转发到请求的URL,在这个过程中,只向服务器发出一次请求.效率当然也就高了。这种方式跳转后,以前的request中存放的变量不会失效,相当于把两个页面拼在一起。
从在浏览器地址栏中显示的URL来看,response.sendRedirect("url"),地址栏中的URL会发生变化,会显示重定向的这个URL的地址,而request.getRequestDispatcher("url").forword(request,response)这种方法,地址栏中的地址是不变的。
从效率和安全角度说,forword方式的跳转更好,只是,forword方式只能将请求发送给同一个web应用中的组件,即url中的“/”相对于当前目录。
第三种利用了PrintWriter在Servlet中输出JavaScript代码,也能实现页面的跳转
PrintWriter out = request.getWriter();
out.println("<script>window.location.href = "url"</script>");
这种方法和response.sendRedirect()的效率是差不多的,也要向服务器发出再次请求才能跳转到的URL。
Servlet开发过程
l webapps中新建应用以及相关目录结构
l 添加lib\servlet-api.jar到classpath中
l 写Servlet类
l 编译servlet类,放到classes的相应package中
l 在web.xml中增加Servlet映射配置(如果有人用一个url访问,tomcat你就运行我这个class,把结果给他)
在程序开发时,如果更新了Servlet类,需刷新一下web.xml(重载)或重启Tomcat即可。