zoukankan      html  css  js  c++  java
  • 2018/12/11 什么是servlet

    早上占坑。


    servlet概念: 

    Java web动态网页开发分两种方式servlet和jsp,但是jsp的实现底层也是通过servlet实现的,所以servlet技术是Java web开发的底层实现方式。

    servlet实际上是jdk中定义的一个servlet接口,实现了该接口的类可以被tomcat等servlet容器调用,在配置文件中配置servlet和url的映射后,servlet就可以供浏览器访问了。

    实际开发中,人们常常将继承了servlet接口的类称为servlet,所以servlet不再单单指servlet接口。但应该明白servlet实际上是一个定义的接口。

    大神对servlet的理解:

    Servlet是sun公司提供的一门用于开发动态web资源的技术。
      Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
      1、编写一个Java类,实现servlet接口。
      2、把开发好的Java类部署到web服务器中。
      按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet

    servlet访问过程:比如通过浏览器访问一个servlet开发的服务,http://www.servlet.com/services/test

    1.客户端浏览器发送http请求给web服务器,tomcat

    2.tomcat解析url,将请求解析到指定的主机host和网站website

    3.tomcat通过配置文件的servlet和url的映射配置发现访问的接口为某一个servlet接口

    4.如果当前访问是第一次访问该servlet,则创建该servlet实例,调用init()方法。已存在实例则直接下一步。

    5.tomcat为该请求创建request实例和response实例,分别封装请求数据和返回数据,(注意,为每个请求创建单独的request和response实例,request实例将请求的数据封装到实例中,且该实例的创建是由tomcat创建的)

    6.tomcat调用servlet的service(request,response)方法,将request和response实例当作参数传入service方法中,接下来就是开发者根据自己的业务需求在service中读取request实例的数据,将处理结果返回给response实例

    7.service方法执行完毕后,返回response处理结果(根据请求类型的不同,可能直接返回response结果,也可能tomcat根据servlet的控制和返回结果进行动态网页的拼接,将拼接的静态网页给web服务器,然后返回给客户端)

    注意:

    1.servlet只创建一个实例,所有请求调用的都是同一个实例

    2.但是为每个请求创建单独的request和response实例作为service方法的参数

    3.因为所有的请求共用一个servlet实例,所以定义的servlet类中的属性变量可以被所有请求访问,因此对于servlet类的属性的访问存在线程安全问题,必须考虑。

    4.这个servlet的生命周期从web服务器启动,第一次servlet访问,创建servlet实例后直到web服务器关闭。(所以,init方法只调用一次)

    5.因为servlet只是一个接口,所以如果直接继承servlet会有很多东西需要自己处理,比如http请求的处理,request实例的创建等,所以Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。

    开发者可以直接继承这两个servlet实现类然后重写部分自己需要的方法,service、doPost、doGet等,就可以实现自己的servlet了。(类似于AbstractCollection的作用,使开发者不必从头实现复杂的所有的接口)

    (通过servlet的原理,就可以理解.net中controller的request、response等这些属性的来源和属性变量的共享是怎么回事了)

    这个过程是简化版的servlet调用过程,可以供理解使用,实际上,有丰富的配置可以供开发者选择,

    比如

    配置load-on-startup来让tomcat启动时就创建servlet实例,然后调用init方法

    配置创建多个servlet实例

    配置多个url映射,通配符*url等

    配置单线程访问等,这些配置可以后续深入学习时再理解。

    关于servlet属性变量的线程安全问题

    如果加synchronized锁来实现,这种做法虽然解决了线程安全问题,但是编写Servlet却万万不能用这种方式处理线程安全问题,假如有9999个人同时访问这个Servlet,那么这9999个人必须按先后顺序排队轮流访问。

    针对Servlet的线程安全问题,Sun公司是提供有解决方案的:让Servlet去实现一个SingleThreadModel接口,如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。(该接口已过时)
      

    查看Sevlet的API可以看到,SingleThreadModel接口中没有定义任何方法和常量,在Java中,把没有定义任何方法和常量的接口称之为标记接口

    经常看到的一个最典型的标记接口就是"Serializable",这个接口也是没有定义任何方法和常量的,标记接口在Java中有什么用呢?

    主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了"Serializable"接口的类的对象就可以被序列化,还有一个"Cloneable"接口,这个也是一个标记接口,在默认情况下,Java中的对象是不允许被克隆的,就像现实生活中的人一样,不允许克隆,但是只要实现了"Cloneable"接口,那么对象就可以被克隆了。

    servlet类和普通类的区别:

    Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。

    到此处,可以补充servlet容器tomcat起到了什么作用。

    tomcat作为容器其实并没有做什么玄学的事情,它仍然是做我们开发常做的事情,调用接口、方法,而已。

    动态网页也不玄,所有的开发捅破窗户纸后其实都不玄,很普通,就是定义方法、定义类,调用方法、调用类。高大上如游戏开发也不外乎这样。

    实际举例:

    配置url Mapping:(web.xml)

      <servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class>
      </servlet>
      //注册servlet的名称
      <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/servlet/ServletDemo1</url-pattern>
      </servlet-mapping>
    
    //配置映射url,映射url支持*通配符,如果url匹配多个,调用最接近的那个。
    

      

    至此,浏览器就可以通过url访问servlet啦!

    补充:控制浏览器如何处理response的数据是由开发者设置的,

    比如浏览器用什么编码解析文本,

    response.setHeader("content-type", "text/html;charset=UTF-8"); 或

    response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");

    浏览器下载的方式处理发送的资源,

    response.setHeader("content-disposition", "attachment;filename="+fileName);

    以html方式处理,以图片方式处理,以文件方式处理,,,等等

    这些都是可以通过response这个类去进行设置的。要熟练掌握response类。

    明天,什么是http协议,它有什么作用,有哪些设置

    
    
  • 相关阅读:
    LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)
    UVA 10564 Paths through the Hourglass(背包)
    Codeforces Round #323 (Div. 2) D 582B Once Again...(快速幂)
    UVALive 3530 Martian Mining(贪心,dp)
    UVALive 4727 Jump(约瑟夫环,递推)
    UVALive 4731 Cellular Network(贪心,dp)
    UVA Mega Man's Mission(状压dp)
    Aizu 2456 Usoperanto (贪心)
    UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
    Aizu 2304 Reverse Roads(无向流)
  • 原文地址:https://www.cnblogs.com/lbzhu/p/10100799.html
Copyright © 2011-2022 走看看