第四天:servlet的生命周期和一些细节问题

1、  servlet的生命周期:

  a)  流程

              i.  Web服务器首先会检查是否装载了该servlet的实例对象。如果装载了直接进行第四步。

              ii.  装载并创建该servlet的实例对象。

              iii. 调用servlet的init方法,这个方法是将该实例对象装载到内存中。

              iv. 创建一个封装http请求对象httpservletrequest和一个响应http的对象httpservletresponse,讲两个参数传到service方法中。

              v. Web应用被重启或者停止的时候,servlet引擎将卸载servlet,在卸载之前调用servlet的destroy方法。

  b)生命全过程

                 i. 加载

                ii.  实例化

                iii.初始化

                iv. 处理请求

                v.退出服务

  c) 开发servlet的有三种方法

                 i.实现servlet接口

                ii. 继承GenericServl

                iii. 通过继承HttpServlet

  d) Get和post提交的区别

                 i. 安全方面:post更加安全,因为get提交的时候会把参数传到地址栏里。。

                ii. 提交内容方面:get提交的数据一般不能大于2k,post是无限制的,但在实际开发中建议不要大于64.

               iii.从速度来看:get的提交速度会比post快。

               iv. 收藏:get可以保留uri中的数据,易于收藏。

2、  使用myeclipse开发servlet

  a) 部署

               i. 首先,我们要知道在哪儿部署??部署什么??部署的时候是在web.xml文件中部署的,部署两个标签,<servlet><servlet-mapping>,<servlet>标签中有两个属性:<servlet-name>和<servlet-class>,<servlet-name>命名可以随意但是要和<servlet-mapping>标签中的<servlet-name>保持一致。<servlet-class>是我们的servlet的所在包是路径以及servlet的名字(说白了就是:包.servlet的名字)。<Servlet-mapping>标签中的<url-pattern>中的路径可以随便写,它就是url中地址中的资源名

  b) 优化myeclipse

              i.validation有很多,包括xml、jsp、jsf、js等等,我们没有必要全部都去自动校验一下,只是需要的时候才会手工校验一下,速度将很快提升好几个档次。windows > perferences > myeclipse > validation将Build下全部勾取消,如果你需要验证某个文件的时候,我们可以单独去验证它。方法是:在需要验证的文件上( 右键 -> MyEclipse -> Run Validation 。

              ii.Window > Preferences > General > Startup andy Shutdown 在这里列出的是MyEclipse启动时加载的模块

              iii. 关闭拼写检查

  c) 给myeclipse制定tomcat

  d) 将项目发布到服务器

               i. 方法一:

      

               ii.  方法二:

      

  e)  java.lang.UnsupportedClassVersionError: Bad version number in .class异常的解决方法

              i. 分析:看到version后可以确定是tomcat和jdk版本不一致的问题

    

3、  Servlet的细节问题

  a)一个注册的servlet可以多次被映射,说白了就是:一个<servlet>(注册servlet)标签可以对应多个<servlet-mapping>(映射servlet到url)标签。

  b) 映射一个servlet的时候可以多层:说白了就是,<url-pattern>标签中的路径可以这样设置:/sdf/sald

  c) 通配符在servlet映射中的用法:

             i. *.扩展名:该扩展名的所有名字都可以访问

             ii. / 路径名/*:/路径名之后随便加,都可以访问。

  d)Servlet的单例问题

             i.所谓的单例怎么在servlet中体现????
说白了就是我们的init方法把servlet实例化到内存中以后,在不关闭web服务器或者重启web应用的时候,我们的这一个servlet实例对象可以一直对请求响应。
因为servlet是单例的,因此会出现线程安全问题,比如:售票系统

    ii. 疑问:售票系统不加同步机制,则会出现问题,什么是同步机制???怎么实现同步机制???

  e)Servlet中<load-on-startup>的配置
如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。

  f)缺省的servlet
如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
什么是缺省的servlet那???
   说白了就是当我们访问servlet的时候出现问题了,web应用就会访问该servlet。

  g) Servlet中的线程安全问题
当多个客户并发访问servlet的时候,我们会为每个线程提供service方法,当他们多个线程中同时访问同一个资源的时候,就可能引发线程安全问题。
怎么解决这一个问题那???

         i.  让变量成为局部变量即可,这样每个线程都访问的是自己的变量就不会发生线程安全问题。

         ii.针对Servlet的线程安全问题,Sun公司是提供有解决方案的:Servlet去实现一个SingleThreadModel接口,如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。
      查看Sevlet的API可以看到,SingleThreadModel接口中没有定义任何方法和常量,Java中,把没有定义任何方法和常量的接口称之为标记接口,经常看到的一个最典型的标记接口就是"Serializable",这个接口也是没有定义任何方法和常量的,标记接口在Java中有什么用呢?主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了"Serializable"接口的类的对象就可以被序列化,还有一个"Cloneable"接口,这个也是一个标记接口,在默认情况下,Java中的对象是不允许被克隆的,就像现实生活中的人一样,不允许克隆,但是只要实现了"Cloneable"接口,那么对象就可以被克隆了。
      让Servlet实现了SingleThreadModel接口,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。
      对于实现了SingleThreadModel接口的ServletServlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。 
   实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。 

       iii.              同步对共享数据的操作
对这里我还存在很大的疑问!!!!!

4、  偶遇java.net.BindException异常,怎么解决???
这个异常查了之后发现是tomcat端口被占用,要么是你的端口和其他的程序端口冲突,要么就是Tomcat没有正常关闭。前者可以把占8080端口的进程杀掉,后者你可以通过shartdown将tomcat手动关闭。

原文地址:https://www.cnblogs.com/huiyuantang/p/5302387.html