Servlet

Servlet

         1.servlet

               ~~servlet是一门开发动态web资源的技术.

               ~~servlet它叫服务器端小应用程序。

               ~~它可以理解服务器端的一个资源,它可以进行请求与响应的处理.

              servlet技术使用

                   sun公司在api中提供了Servlet接口, 对于我们开发一个servlet它步骤有两个.

                            1.实现或继承 Servlet接口或  GenericSerlvet,HttpServlet。

                             2.在web.xml文件对Servlet进行配置.

                                               <servlet>

                                                        <servlet-name>任意起的一个名称,一般会使用servlet的类名    </servlet-name>

                                                        <servlet-class>servlet的全名  就是包名.类名.</servlet-class>                                                                   

                                               </servlet>

                                               <serlvet-mapping>

                                                        <servlet-name>要与上面的servlet-name的值一样</servlet-name>

                                                        <url-pattern>/名称</url-pattern>

                                               </servlet-mapping>

         2.可以配置一个缺省的Servlet

                            1.写法: 

                                     <servlet-mapping>

                                               <servlet-name>myfirst</servlet-name>

                                               <url-pattern>/</url-pattern>

                                      </servlet-mapping>

                            2.当请求静态资源时,如果找不到,则执行缺省的Servlet

                                     if("1.jpg"找到了){

                                               显示图片

                                     }else{

                                               没有找到 显示404

                                     }

                   这个缺省的Servlet一般不配置,为什么?在Tomcat的web.xml中有

                            ------------------------------------------------------

                                     关于请求方式  get与post

                                               在浏览器上直接输入url----get请求.

                                               如果想要以post方式提交,只能通过表单,设置method=post.

                   --------------------------------------------------------------------------

思考 : doGet()能处理get请求,doPost()可以处理post请求  它们与Service()方法的关系 ?

                            当用户发起请求起,始终调用的是service()方法,而这个方法内部会进行判断

                            并决定是调用 doGet(),还是doPost()

                            而咱们自己定义的Servlet又重写了doGet(),doPost()

                   结论:不要自己重写service()方法,因为父类有这个方法,一般只要重写doGet(),doPost()就可以了

                   扩展:模板方法设计模式

                   public class A{

                            service(){

                                doGet();

                                doPost();

                            }

                            public abstract void  doGet();

                            public abstract void  doPost();

                   }

                   public class B extends A{

                            public void doGet(){

                            }

                            public void doPost(){

                            }

                   }

                   public static void main(String args[]){

                            A a = new B();

                            a.service();

                   }                

研究servlet的生命周期(******************************)

The servlet is constructed, then initialized with the init method. Any calls from clients to the service method are handled.

The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.

                   1.在默认情况下,Servlet生命周期执行过程如下:

                     在用户第一次请求时:

                            1.实例化:构造方法1次

                            2.初始化:(init):1次

                            3.服务:(service),以后每次请求,都会直接执行service()  :N次

                            4.销毁:当服务器停止或应用被移除,此时销毁destory()方法执行: 1次                       

我们开发Servlet可以有三种方式.

                                               1.实现javax.servlet.Servlet接口

                                               2.继承  javax.servlet.GenericServlet

                                               3.继承  javax.servlet.http.HttpServlet

          问题一:我们提交请求时, get请求会调用doGet方法,post请求会调用doPost方法?

                   :因为在HttpServlet的service方法中,它进行了重写,重写后分根据请求方式不同,调用不同的方法.

                                                        String method=request.getMethod();      

                                                        if("get".equals(method)){

                                                                 doGet();

                                                        }else if("post".equals(method)){

                                                                 doPost();

                                                        }

          问题二:为什么我们重写时,只重写了无参数的init方法,不需要重写有参数的init

                   在GenericServlet 中定义了一个无参数init方法,重写Servlet接口中的init(ServletConfig config)方法.

                   当servlet对象创建后会调用有参数的init方法。在有参数的init方法中又调用了无参数的init方法。

                    对于我们来说,我们只需要重写无参数的init就可以。

                   --------------------------------------------------------------------------------------------------------

                            关于servlet的自动加载.

                                     正常情况下,servlet是第一次被访问时,会创建servlet实例。并初始化,也就是调用init方法。

                                     我们可以通过对servlet进行配置,让servlet可以随着服务器的启动而自动创建与初始化.

                                     只需要在web.xml文件中在配置servlet时,加上<load-on-startup>       

                                     servlet跟随服务器启动的作用是什么?

                                               根据特点来分析,当前servlet的init方法是服务器启动了,init方法就被调用了,

                                               那么我们就可以将一些需要提前加载的信息在servlet的init方法中定义。

线程安全

                   启发:

                        说明servlet不是线程安全的,而且它设计目标就是采用多线程来处理用户请求

                   线程安全问题解决方法:

                            1.synchronized:线程同步

                            2.用单线程:就是实现SingleThreadModel接口

                            总结:这两种方法都不行,违背了设计意图!!!

                            最终解决办法:

                                     程序员自己注意,不要定义成员变量,尽量用局部变量

                                     合理决定在Servlet中定义的变量的作用域

                   ------------------------------------------------------------------------------------------------------------

                            关于url-pattern的写法.

                                     url-pattern它的作用是什么?

                                               它的值要与浏览器输入的地址相匹配,通过url-pattern可以查找到servlet-name,再通过serlvet-name可以查找到对应servlet类.

                                     它的写法有两种:

                                               1.完全匹配  要求以/开始,名称与url一致.

                                               2.使用通配符  *

                                                        1.目录匹配   以/开始,以*结束.

                                                        2.扩展名匹配.    不能以/开始,以*.xxx对束

                                               最经典错误   /*.do     

                                               优先级:   完全匹配>目录匹配>扩展名匹配

                            --------------------------------------------------------------------------------

                            访问servlet时的路径问题(客户端访问服务器端资源路径问题):

                                     访问一个servlet它的路径有两种写法,一种是绝对路径,一种是相对路径.

                             绝对路径:

                                                 1.带协议的绝对路径

                                                 <a href="http://localhost/day09/demo2">demo2 servlet</a>

                                                 2.不带协议的绝对路径

                                                 <a href="/day09/demo2">demo2 servlet</a>                                          

                                                  在开发中,带协议的绝对路径一般应用于访问站外资源。而不带协议的绝对路径我们一般是在站内访问时使用的,也是推荐使用的。

                            相对路径

                                               相对路径:

                                               <a href="./demo2">demo2 servlet</a>

                                               对于当前路径下的资源我们一般写成:

                                               <a href="demo2">demo2 servlet</a>

                                     分析:       

                                               访问admin.html的路径是: http://localhost/day09/admin.html

                                               访问demo2Servlet的路径是:http://localhost/day09/demo2

                                               通过上面的路径分析,发现admin.html与demo2是同级别,那么它们相对关系就是当前路径下。

                                               如果将admin.html放置在main目录下.

                                               访问admin.html的路径是: http://localhost/day09/main/admin.html

                                               访问demo2Servlet的路径是:http://localhost/day09/demo2

                                               那么相对路径就需要改变。

                                               <a href="../demo2">demo2 servlet</a>

                            总结:

                                     我们在开发中建议使用不带协议的绝对路径.

                                     它的写法是  /虚拟目录名称/资源路径

                                     根据以上的分析,说明在客户端的 /代表的是就相当于服务器根目录.

                            ------------------------------------------------------------------------------------------

                 ServletConfig对象

         ServletConfig是Servlet的一个配置对象.每一个servlet都有一个对应的ServletCofnig。

         ServletConfig是由web服务器创建的,它通过Servlet的init方法传递到了Servlet中.

         ServletCofnig作用:(它是servlet的一个配置对象)

                   1.可以获取Servlet的名称   getServletName();---web.xml文件中的<servlet-name>的值.

                  2.可以获取初始化参数getInitParameter(String name); 根据name获取value

getIniteParameterNames();  获取所有的name值,它返回的是一个Enumeration.

对于Enumeration它相当于是一个Iterator Iterator            hasNext() next()

                                                                 Enumeration  hasMoreElement()   nextElement();

                   3.可以获取ServletContext对象。通过代码去测试一下这些操作

问题:我们在Servlet中怎样获取ServletConfig对象

                            我们现在知道,ServletConfig对象是由服务器创建,通过Servlet的init方法传递到Servlet中.在Servlet类中通过this.getServletConfig()就获取了ServletConfig对象,当用getServletConfig()获取时,不能重写init方法.还可以用init(ServletConfig config)获取。

初始化参数 

在servlet中配置

<init-param>

         <param-name>name</param-name>

         <param-value>value</param-value>

</init-param>

初始化参数的作用        

我们可以将一些servlet运行时需要加载常量定义在初始化参数中,当我们需要使用时,可以直接通过ServletConfig获取到这些值。

ServletConfig总结:

         1.每一个Servlet都有自己的ServletConfig对象.

         2.ServletCofnig对象是由服务器创建,通过Servlet的init方法传递到Servlet中。

         3.ServletConfig对象代表的是Servlet的配置对象,可以通过它获取Servlet的名称与相关初始化参数。

         4.在Servlet中要获取ServletConfig对象,只需要直接调用getServletConfig()就可以。

         5.可以通过ServletConfig获取ServletContext对象.

-----------------------------------------------------------------------------------------------------------    

   ServletContext对象

                     它是一个全局的web容器对象.它代表的就是当前工程。

                   ServletContext代表一个web应用,在这个web应用中所有Servlet使用的就是这一个。每一个Servlet都有ServletConfig。因为在一个web应用中就一个ServletContext,所有的servlet使用的是同一个ServletContext,那么我们这些servlet就可以通过serlvetContext去实现通信。ServletContext对象它是一个容器对象。(大家将其想像成是一个map集合)我们将这种功能的对象叫做域对象(上下文对象),作为一个全局范围的域对象来用(四大域作用范围),可以实现应用范围的数据共享.实现各个Servlet之间信息共享

实现原理:

                                     就是在全局范围内维护一个Map集合

                                     setAttrbite(key,Value);

                                     Object obj = getAttribute(key);

                                     removeAttribute(key);

                            ----------------------------------------------------------------------        

                                 案例    利用ServletContext对象读取资源文件   

                                               1.问题:我们在servlet中怎样获取ServletContext对象,它是由谁创建的?

                                                        ServletContext对象是由服务器创建,它代表web应用.

                                                        要想获取我们可以通过ServletConfig对象去获取.                       

                                                        this.getServletConfig().getServletContext();

                                                        this.getServletContext();这种方式底层也是通过ServletConfig获取的.

                                                       

         2.ServletContext的功能有什么

                            1.可以完成Servlet与Servlet之间的通信.

                                                                 setAttribute(String name,Object value)

                                                                 getAttribute(String name);

                                                                 removeAttribute(String name);

                                                                

                            2.可以设置全局初始化参数.

                               1.在web.xml文件中可设置全局初始化参数

                                                                           <context-param>

                                                                                    <param-name>global</param-name>

                                                                                    <param-value>this is message</param-value>

                                                                           </context-param>

                             

                            2.怎样获取全局初始化参数

                                                                           getInitParameter(String name);

                                                                           getInitParameterNames();

                                                                                                                        

       例子:我们在全局初始化参数中可以设置一个变量来描述整个web应用的字符编码.我们在任意的一个servlet中都可以获取到这个字符编码。全局初始化参数它是针对于web工程共享的信息。全局初始化参数通过ServletContext对象实现数据共享

             案例--- 统计站点访问次数              

                     3.获取Mime类型.

                                               String getMimeType(String name)文件下载中用到

                     4.在ServletContext中有一些获取路径操作. 

                                      --getRealPath(String path); 它返回的是一个String

                                        例如:context.getRealPath("/"); 获取的是当前web应用在磁盘上的绝对路径.                 E:apache-tomcat-7.0.26webappsday09

                                       --getResource(String source);  它返回的是一个URL

              例如:context.getResource("/");  返回的是  /localhost/day09

              --getResourceAsStream(String path)   它返回的是一个InputStream

                                         例如:context.getResourceAsStream("/a.txt");得到一个指向了WebRoot下的a.txt文件的一个输入流。

                                     --------------------------------------------------------------------------------------------------

                                               利用ServletContext对象读取资源文件---关于路径问题

                                              

                            总结:

                            getRealPath() 它可以得到tomcat下的web应用中的文件的绝对磁盘路径。           

                            类.class.getResource().getPath();是获取classpath路径。就是我们的bin或classes目录路径。                           

                           相对路径:/WEB-INF/classes/1.jpg而相对于谁?第一个/代表当前web应用程序

                            绝对路径: C:apache-tomcat-6.0.37webappsday07_00_servlet/WEB-INF/classes/1.jpg

                            getServletContext().getRealPath("/WEB-INF/classes/1.jpg");//相对于本应用,咱们现在这个路径是绝对定位

原文地址:https://www.cnblogs.com/lulu638/p/4234751.html