JavaWEB的Servlet

来源:互联网 发布:自己制作名片软件 编辑:程序博客网 时间:2024/06/03 17:59

  最近几天我们学习了一下JavaWEB的Servlet,下边就来讲一讲这个Servlet。

  1. Servlet概述

  ① Servlet是一个与平台无关的服务器组件,是一个Java类,运行在WEB服务器中。

  ② 创建一个Servlet的六个方法,四个生命周期相关的方法,还有getServletConfig和getServletInfo。

  ③ Servlet若想在浏览器中直接访问,就必须要在web.xml中对这个Servlet进行注册和映射请求路径。需要注意的是:我们可以在web.xml文件中注册某个Servlet时,通过设定<load-on-startup>节点的值来决定WEB容器创建当前Servlet实例和初始化当前Servlet的时机和顺序。值为负数时表示WEB服务器加载当前应用时就对这个Servlet创建实例和初始化(调用无参构造器和init方法),值为整数时,表示当前Servlet响应请求时才会对其创建实例和初始化,且正数越小,创建实例和初始化的时机越早。

  2. Servlet容器

  说白了就是WEB服务器,再说的白一点就是Tomcat/jboss等WEB服务器,Servlet容器负责浏览器(客户)和WEB服务器的通信以及调用Servlet的生命周期(四个,无参构造器,init,service,destroy)的方法。这些服务器负责对定义的Servlet进行反射创建实例,初始化,响应请求,具体是通过调用Servlet当中的无参构造器,init方法,service方法来实现,并且对service方法中的ServletConfig入参进行实例化,具体实例化的实现类是根据不同的WEB容器的实现类来进行传入参数的

  需要注意的是:在整个Session中,WEB容器只会对某一个Servlet创建一次实例且只会初始化一次,所以Servlet是单实例的,具有线程不安全的可能,所以我们尽量不要在某个Servlet中定义属性。而每次请求,WEB容器都会调用service方法。

  3.ServletConfig子接口

  ① 顾名思义,这个接口可以获取当前Servlet的配置信息

  ② 还可以获取当前WEB应用的上下文:ServletContext

  ③ 主要通过四个方法来获取:getInitParameter(String name)/getInitParameterNames()/getServletName()。

  ④ 因为Servlet中的init方法是在WEB容器创建当前Servlet之后立即被调用的,同时对init方法中的入参ServletConfig进行初始化,那么我们就可以通过这个ServletConfig来获取在web.xml中配置的当前的Servlet的初始化参数了。

  4.ServletContext

  ① 这个子接口的对象也是由WEB服务器的实现类来完成实例化的。

  ② Servlet引擎为每一个WEB程序都创建了一个对应的ServletContext对象,且多个Servlet共用一个ServletContex对象。

  ③ 这个接口的对象代表的是当前的整个WEB应用,我们可以通过这个对象获取到一切与当前WEB引用相关的信息。

  ④ 这个ServletContext对象被包含在每一个ServletConfig中,所以我们可以通过InIt方法中的ServletConfig来获取这个对象。

  ⑤ ServletContext对象的获取WEB信息的方法有

      a:获取当前WEB应用的初始化参数:servletConfig.getInitParameter(String name)

      b:获取某个文件在发布后的WEB应用中的绝对路径:getRealPath(String path)  需要注意的是,这个path是相对于发布后的当前WEN应用的相对路径。  重要,有趣,搞一搞

      c:获取当前WEB应用名称:getContextPath()

      d:获取某个资源文件的输入流:getResourceAsStream(String path) 需要注意的是这个path也是发布后当前文件相对于WEB应用的根路径。(对比通过ClassLoader来获取某个资源文件的输入流,不同的是参数直接写明文件名称即可)

      e:有关Attribute的方法暂时不讲,之后在Session时在进行讲述。

  5.HTTP概述

  ① HTTP协议:HTTP协议是一套规则,规定了浏览器和WEB服务器之间一问一答进行交互的规则。在这个过程中定义了浏览器和WEB服务器之间传输数据的过程和数据的格式

  ② HypeText Transfer Protocol:超文本传输协议,是TCP/IP协议簇中的一个应用层的协议,用于定于浏览器和WEB服务器之间传输数据的过程和数据的格式。

  ③ HTTP的回话方式:浏览器和WEB服务器之间的连接时短暂的,每次连接只处理一个请求和一个响应。浏览器与WEB服务器之间的每次连接通讯都是独立的请求和响应对。

  ④ HTTP的请求消息的结构:一个请求行,一个请求头,实体内容(请求消息的实体内容就是post请求中的表单元素和表单值

  ⑤ HTPP的响应消息的结构:一个状态行,一个响应头,多个实体内容(响应消息的实体内容就是我们在browser上看到的sourcecode

  ⑥ HTTP请求的两种方式get和post

       get:通常直接在地址栏输入url或者超链接或者表单的method="get"都是get的请求方式,这种方式的请求消息中没有实体内容,超链接或者表单带过来的参数是以?和&的形式连接在url之后的。传递的参数的数据量小且不安全。

       post:通常表单的method="post"是HTTP传输协议的post请求方式,这种方式将表单元素和表单值作为请求消息的实体内容,传递的数据量很大。

  6. ServletRequest

  ① 这个接口封装了某次请求的所有信息,可以通过其实现类的方法来获取这些信息。

  ② 我们可以在当前Servlet的service方法中获取这个对象,是因为当请求发出时,WEB容器对当前Servlet的init方法中的ServletRequest进行了初始化,将对应WEB容器的API的ServletRequest接口的实现类的对象注入了这个参数。所以这个ServletRequest参数也是服务器传递的。不同的WEB服务器对这些Java定义的接口有不同的实现。

  ③ 具体方法

  getParameter(String name)

  getParameterMap():获取表单中的键值对,key是表单元素的name,value是表单元素的值,需要注意的是值的类型时String[]数组类型的,因为可能存在多选框

  getParameterNames():获取表单中元素的name组成的String数组

  getParameterValues:获取表单中元素的值组成的String数组

  以下的方法需要将ServletRequest向下强转为HttpServletRequest才可以使用(HttpServletRequest) servletRequest

  ① getMethod():获取HTTP请求的方式

  ② getRequestURI():获取请求的URI。需要注意的是URI和URL的区别,URL是RUI的具体实现,统一资源定位符。

  ③ getQueryString():获取get请求方式的参数。

  ④ getServletPath():获取URL中的action,即表单中的action属性的值。

  ⑤ 和Attribute相关的方法,暂时不讲,我们到Session中再一起讲述。

  7.ServletResponse

  ① 这个接口和ServletRequest接口很类似,都是由WEB容器进行初始化的,里边可以封装了响应的信息,如果你想给用户什么信息,调用其方法即可。

  ② 几个比较常用的方法

   getWriter().print("内容")可以直接将其中的字符串作为响应消息的实体内容,从而作为页面的源码让用户可以看到。

   setContentType("application/msword")设置响应的实体内容的格式。具体的格式的参数内容可以在WEB服务器安装目录下的conf/web.xml中进行查找。

  强转为HttpServletResponse接口之后,可以使用sendRedirect()方法来进行请求的重定向,这个方法我们到下边的请求的重定向再讲述,很重要。

  8. GenericServlet

  ① 这是一个抽象类,实现了三个接口:Servlet/ServletConfig/Serializable。

  ② 重写了Servlet接口中的方法,并且提供了具体的实现;重写了ServletConfig中的方法,并且提供了具体的实现。在这两类重写的方法中,关键连接点是在GenericServlet中定义了一个属性变量servletConfig,并且利用Servlet的生命周期方法init(SrvletConfig)对其进行了初始化,然后在ServletConfig接口的重写方法中利用这个servletConfig进行方法重写的具体实现。需要注意的是:GenericServlet中还重新定义了一个不带参数的init()方法,这个方法是为了让子类可以重写它从而获取到当前子类Servlet的初始化参数。我们不建议直接重写GenericServlet中的盛名周期方法init(ServletConfig),因为若是在重写的init(ServletConfig)方法中没有使用super()的话,就无法将GenericServlet中的servletConfig属性进行初始化,从而导致之后的重写的实现方法都有问题。

  这个抽象类只是抽象了service(ServletRequest arg0,ServletResponse arg1)方法。

  因为在这个抽象类中完成了众多方法的实现,所以我们在使用的时候继承让我们的Servlet继承这个GenericServlet抽象类再来开发就会简便许多。这也正是这个抽象类存在的意义

  9. HttpServlet

  虽然有了GenericServlet这个重写了Servlet和ServletConfig的方法的抽象类的存在,但是有时我们希望直接使用HttpServletRequest和HttpServletResponse的方法而不要再每一次都去强转,或者我们希望根据请求方式的不同来分开处理,那么我们就需要用到HttpServlet了。

  其实我们在实际开发中,创建一个新的Servelt都是继承这个HttpServlet。

  它是一个继承了抽象类的抽象类类,这个类针对HTTP请求定制。

  我们直接继承这个类的好处是:不用再强转ServletRequest了,还可以针对不同的请求方式来调用其不同的doXXX()方法。