JSP和SERVLET区别

来源:互联网 发布:html源码metro 编辑:程序博客网 时间:2024/05/16 05:03

                                

JSPSERVLET到底在应用上有什么区别,很多人搞不清楚。我来胡扯几句吧。简单的说,SUN首先发展出SERVLET,其功能比较强劲,体系设计也很先进,只是,它输出HTML语句还是采用了老的CGI方式,是一句一句输出,所以,编写和修改HTML非常不方便。 

  后来SUN推出了类似于ASP的镶嵌型的JSP,把JSP TAG镶嵌到HTML语句中,这样,就大大简化和方便了网页的设计和修改。新型的网络语言如ASPPHPJSP都是镶嵌型的SCRIPT语言。 

  从网络三层结构的角度看,一个网络项目最少分三层:data layer,business layer, presentation layer。当然也可以更复杂。SERVLET用来写business layer是很强大的,但是对于写presentation layer就很不方便。JSP则主要是为了方便写presentation layer而设计的。当然也可以写business layer。写惯了ASPPHPCGI的朋友,经常会不自觉的把presentation layerbusiness layer混在一起。就象前面那个朋友,把数据库处理信息放到JSP中,其实,它应该放在business layer中。 

  根据SUN自己的推荐,JSP中应该仅仅存放与presentation layer有关的东东,也就是说,只放输出HTML网页的部份。而所有的数据计算,数据分析,数据库联结处理,统统是属于business layer,应该放在JAVA BEANS中。通过JSP调用JAVA BEANS,实现两层的整合。 

  实际上,微软前不久推出的DNA技术,简单说,就是ASP+COM/DCOM技术。与JSP+BEANS完全类似,所有的presentation layerASP完成,所有的business layerCOM/DCOM完成。通过调用,实现整合。 

为什么要采用这些组件技术呢?因为单纯的ASP/JSP语言是非常低效率执行的,如果出现大量用户点击,纯SCRIPT语言很快就到达了他的功能上限,而组件技术就能大幅度提高功能上限,加快执行速度。 

  另外一方面,纯SCRIPT语言将presentation layerbusiness layer混在一起,造成修改不方便,并且代码不能重复利用。如果想修改一个地方,经常会牵涉到十几页CODE,采用组件技术就只改组件就可以了。 

综上所述,SERVLET是一个早期的不完善的产品,写business layer很好,写presentation layer就很臭,并且两层混杂。 

  所以,推出JSP+BAEN,用JSPpresentation layer,BAENbusiness layerSUN自己的意思也是将来用JSP替代SERVLET。 

  可是,这不是说,学了SERVLET没用,实际上,你还是应该从SERVLET入门,再上JSP,再上JSP+BEAN。 

  强调的是:学了JSP,不会用JAVA BEAN并进行整合,等于没学。大家多花点力气在JSP+BEAN上。 

在补充几句: 

  我们可以看到,当ASP+COMJSP+BEAN都采用组件技术后,所有的组件都是先进行编译,并驻留内存,然后快速执行。所以,大家经常吹的SERVLET/JSP先编译驻内存后执行的速度优势就没有了。 

反之,ASP+COM+IIS+NT紧密整合,应该会有较大的速度优势呈现。而且,ASP+COM+IIS+NT开发效率非常高,虽然BUG很多。 

  那么,为什么还用JSP+BEAN?因为JAVA实在前途远大。微软分拆后,操作系统将群雄并起,应用软件的开发商必定要找一个通用开发语言进行开发,JAVA一统天下的时机就到了。如果微软分拆顺利,从中分出的应用软件公司将成为JAVA的新领导者。目前的JAVA大头SUNIBM都死气沉沉,令人失望。希望新公司能注入新活力。不过,新公司很有可能和旧SUN展开JAVA标准大战,双方各自制定标准,影响JAVA夸平台。 

  另外,现在的机器速度越来越快,JAVA的速度劣势很快就可以被克服。

什么是Servlet?

一个servlet就是Java编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过请求-响应编程模型来访问的应用程序。虽然servlet可以对任何类型的请求产生响应,但通常只用来扩展Web服务器的应用程序。Java Servlet技术为这些应用程序定义了一个特定于HTTP的 servlet类。

javax.servletjavax.servlet.http包为编写servlet提供了接口和类。所有的servlet都必须实现Servlet接口,该接口定义了生命周期方法。

Servlet的生命周期

一个servlet的生命周期由部署servlet的容器来控制。当一个请求映射到一个servlet时,该容器执行下列步骤。

1.     如果一个servlet的实例并不存在,Web容器

a.   加载servlet类。

b.   创建一个servlet类的实例。

c.   调用init初始化servlet实例。该初始化过程将在初始化servlet中讲述。

2.     调用service方法,传递一个请求和响应对象。服务方法将在编写服务方法中讲述。

如果该容器要移除这个servlet,可调用servletdestroy方法来结束该servlet。结束过程将在结束Serlvet中讨论。

Servlet运行时的基本原理

1)、当WEB客户请求Servlet服务或当WEB服务启动时,容器环境加载一个Java Servlet类。

2)、容器环境也将根据客房请求创建一个Servlet对象实例,或者创建多个Servlet对象实例,并把这些实例加入到Servlet实例池中。

3)、容器环境调用Servlet的初始化方法HttpServlet.init()进行Servlet实例化。在调用初始化时,要给init()方法传入一个ServletConfig对象,ServletConfig对象包含了初始化参数和容环境的信息,并负责向servlet传递信息,如果传递失败,则会发生ServletExceptionServlet将不能正常工作。

4)、容器环境利用一个HttpServletRequestHttpServletResponse对象,封装从Web客户接收到的HTTP请求和由Servlet生成的响应。

5)、容器环境把HttpServletRequestHttpServletResponse对象传递给HttpServlet.Service()方法。这样,一个定制的Java Servlet就可以访问这种HTTP请求和响应接口。Servlet()方法可被多次调用,各调用过程运行在不同的线程中,互不干扰。

6)、定制的Java ServletHttpServletRequest对象读取HTTP请求数据,访问来自HttpSessionCookie对象的状态信息,进行特定应用的处理,并且用HttpServletResponse对象生成HTTP响应数据。

7)、当WEB服务器和容器关闭时,会自动调用HttpServlet.destroy()方法关闭任何打开的资源,并进行一些关闭前的处理。

servlet 的生命周期。 

Servlet 运行在 Servlet 容器中,其生命周期由容器来管理。 Servlet 的生命周期通过 Servlet 接口中 init ()、 service ()、 destroy ()方法来表示。 

Servlet 的生命周期包含了下面 个阶段。 

1)       加载和实例化 

Servlet 容器负责加载和实例化 Servlet 。当 Servlet 容器启动时,或者在容器检查到需要这个 Servlet 来响应一个请求时,创建 Servlet 实例。当 Servlet 容器启动后,它必须要知道所需的 Servlet 类在什么位置, Servlet 容器可以从本地文件系统、远程文件系统或者其他网络服务器中通过类加载器加载 Servlet 类,成功加载后,容器创建 Servlet 实例。因为容器是通过 Java 的反射 API 来创建 Servlet 实例,调用的是 Servlet 的默认构造函数,也就是那个不带参数的构造函数,所以我们在编写 Servlet 类的时候,不应该提供带参数的构造函数。——这也就是为什么 Servlet 类可以不写构造函数的原因。 

2)       初始化 

在 Servlet 实例化之后,容器必须调用 Servlet 的 init ()方法初始化这个对象。初始化的目的是为了让 Servlet 对象在处理客户请求前完成一些初始化工作,如建立数据库连接,获取配置信息等。对于每一个 Servlet 实例, init ()方法只能被调用一次。在初始化期间, Servlet 实例可以使用容器为它准备的 ServletConfit 对象从 web 应用程序的配置信息(在 web.xml 中配置)中获取初始化的参数信息。在初始化期间,如果发生错误, Servlet 实例可以抛出异常来通知容器。 

3)       请求处理 

Servlet 容器调用 Servlet 的 service ()方法对请求进行处理。要注意的是,在 service ()方法调用之前, init ()方法必须成功执行。在 service ()方法中, servlet 实例通过 ServletRequest 对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用 servletResponse 对象的方法设置响应信息。 

4)       服务终止 

当容器检测在一个 Servlet 实例应该从服务中被移除的时候,容器就会调用实例的 destroy ()方法,以便让该实例可以释放它所使用的资源,保存数据到持久存储设备中。当需要释放内存或者容器关闭时,容器就会调用 Servlet 实例的 destroy ()方法。在调用 destroy ()方法后,容器会释放这个 Servlet 实例,该实例随后会被 java 的垃圾收集器回收。 

  

在整个 Servlet 的生命周期过程中,创建 Servlet 实例、调用实例的 init ()和 destroy ()方法都只进行一次,当初始化完成后, Servlet 容器会将该实例保存在内存中,通过调用它的 service ()方法,为接收到的请求服务。

servlet是服务器端的程序,动态生成html页面发到客户端,但是这样 

程序里有许多out.println(),javahtml语言混在一起很乱。所以 

后来推出了jsp。其实jsp就是servlet,每一个jsp在第一次运行时被 

转换成servlet文件,再编译成.class来运行。 

有了jsp,因此在MVC模式中servlet不再负责生成html页面,转而担任 

控制程序逻辑的作用,控制jspjavabean之间的流转。 

ServletJsp的区别 

    * Servlet中没有内置对象,原来Jsp中的内置对象都是必须通过HttpServletRequest对象,或由 

       HttpServletResponse对象生成。 

    * 对于静态的HTML标签,Servlet都必须使用页面输出流诼行输出。 

       总之,JspServlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,至于Jsp中的 

       Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service 

       方法用于生成对客户端的响应。 

jspservlet的实质是一样的,jsp最终还是编译成servlet

一、jsp最终还是编译成servlet,所以jspservlet慢。

二、jsp负责前台页面显示,servlet负责业务控制。 

1jsp是由servlet发展演变而来的,jsp在运行的时候最终将会被转译成一个servlet。 

2、在jsp中可以使用的存值对象在servlet中大多数都能使用。 

3jsp能够实现的功能servlet都能实现。 

4、一般情况下,我们在注重页面显示的时候使用jsp,在注重跳转控制的时候使用servlet。 

来历:首先sun提出的是Servlet体系,这个体系使得使用JAVA的程序员也能开发基于B/S架构的WEB应用程序,使用Servlet类将HTTP请求和响应封装在标准JAVA类中来实现各种WEB应用方案。这一步也是sunJ2EE架构中的最关键的一步。

随着大量的B/S架构程序开发出来以后,人们发现Servlet类的编写是非常繁琐的,主要集中在几个问题上:首先有大量冗余代码,这些代码在每个servlet类中都是一模一样或者基本近似的,其次是开发Servlet的程序员很少有精通美工的,导致使用Servlet开发无法方便的做到各种页面效果和丰富多彩的风格,这个时候sun借鉴了微软的ASP方式,正式提出JSP(也就是Servlet 1.1),JSP推出后,JAVA程序员也能象ASP的程序员那样将服务端代码添加在已经由美工设计好的静态页面上,经过一个JSP容器对JSP文件进行自动解析并转换成Servlet类来交给WEB服务器运行。这么一来,极大的提高了工作效率。

人的渴望总是无止境的~~,随着JSP的广泛应用和各种设计模式的盛行,人们发现JSP也暴露了大量的问题:首先,夹杂服务端代码的JSP文件给后期维护和页面风格再设计带来大量阻碍,美工在修改页面的时候不得不面对大量看不懂的服务端代码,程序员在修改逻辑的时候经常会被复杂的客户端代码搞昏。交叉的工作流使得JSP面临大量的困境。这直接导致了servlet1.2的出台,sun在这一版中充分倡导了MVC的概念,大量页面标签的使用使得交叉工作流变的稍微的容易了,服务端标签的兼容性使得美工也可以直接随意移动这些标签而得到对应的效果。但是又暴露了一些问题:设计的差的标签使得程序的错误得不到检测,不成熟的代码导致无法真正的使服务端标签可以和客户端标签那样随意移动而不会导致逻辑错误。这些都有待我们去解决~

-Servlet的开发 

      Servlet通常称为服务器端小程序,用于处理和响应客户端的请求。 

      Servlet是个特殊的Java类,这个Java类必须继承HttpServlet。每个Servlet可以响应客户端的请求。 

      Servlet提供了不同的方法用于响应客户端请求。 

      * doGet   : 用于响应客户端的get请求 

      * doPost  : 用于响应客户端的post请求 

      * doPut   : 用于响应客户端的put请求 

      * doDelete: 用于响应客户端的delete请求 

      * service(HttpServletRequest  request,   [可以响应客户端所有类型的请求

                       HttpServletResponse response) 

                       throws ServletException,java.io.IOException 

其他方法 

      * init(Servletconfig config)  : 创建Servlet实例时,调用的初始化方法。 

      * destory()   : 销毁Servlet实例时,自动调用的资源回收方法。 

-Servlet的配置 

      编译好的Servlet源文件并不能响应用户请求,还必须将其编译成class文件。将编译后的.class 

      文件放在WEB-INF/classes路径下,如果Servlet有包,则还应该将class文件放在对应的包路径下。 

      为了让Servlet能响应用户请求,还必须将Servlet配置在Web应用中。配置Servlet时,需要修改 

      web.xml文件。 

     配置Servlet需要配置两个部分:   

      * 配置Servlet的名字:对应web.xml中的<servlet/>元素 

      * 配置ServletURL :对应web.xml中的<servlet-mapping/>元素 

-Servlet的生命周期 

     Servlet在容器中运行,其实例的创建以及销毁等都不是由程序员决定的,而是由容器进行控制的。 

     Servlet的创建有两个选择: 

       *客户端请求对应的Servlet时,创建Servlet实例:大部分的Servlet都是这种Servlet 

       *Web应用启动时,立刻创建Servlet实例:即load-on-startup Servlet 

Servlet的生命周期

     Begin 

            ---> 创建实例完成 

            ---> 初始化[init] 

            ---> 响应客户端请求[doGet,doPost,service] 

            ---> 被销毁[destroy] --->    

     End 

-使用Servlet作为控制器 

     使用Servlet作为表现层的工作量太大,所有的HTML标签都需要使用页面输出流生成。 

     因此使用Servlet作为表现层有如下三个劣势: 

     * 开发效率低,所有的HTML标签都需使用页面输出流完成 

     * 不利于团队协作,美工人员无法参与Servlet界面的开发 

     * 程序可维护性差,即使修改一个按钮的标题,读需要重新编辑Java代码,并重新编译 

使用ServletMVC的架构实现: 

     Jsp页面--> Servlet程序 --> Servlet根据条件转发新的Jsp页面 

-load-on-startup Servlet 

     Servlet实例化的时机还有在Web应用启动时,即load-on-startup Servlet 

     应用启动时就启动的Servlet,通常是用于某些后台服务的Servlet,或者拦截很多请求的Servlet; 

     这种Servlet通常作为基础的Servlet使用,提供重要的后台服务。 

web.xml中的配置: 

     在<servlet/>元素中增加元素 

         <load-on-startup>1</load-on-startup> 

-访问Servlet的配置参数 

     配置Servlet时,还可以增加附加的配置参数,通过使用配置参数,可以实现更好的解除耦合, 

     避免将所有的参数以硬编码方式写在程序中。 

     访问Servlet配置参数要通过ServletConfig类的实例完成,ServletConfig提供如下方法: 

         java.lang.String getInitParameter(java.lang.String name) [获取初始化参数

原创粉丝点击