Servlet知识讲解

来源:互联网 发布:日本买mac口红便宜吗 编辑:程序博客网 时间:2024/06/09 20:35

一、Servlet介绍

1、Servlet简介

           【1】、Servlet是SUN公司提供的一门用于开发动态web资源的技术。

           【2】、SUN公司在其API 中提供了一个servlet接口,用户弱项开发一个动态web资源(即开发一个JAVA程序向浏览器输出数据),需要完成以下2个步骤:

                  · 编写一个java类,实现servlet接口;

                  · 把开发好的Java类部署到web服务器中。

           【3】、快速入门,用servlet向浏览器输出“hello servlet!”,阅读Servlet API解决两个问题:

                  · 输出hello servlet的java代码应该写在Servlet的那个方法内?

                  · 如何向IE浏览器输出数据?

           【4】、 Servlet在web应用中的位置:

                  

2、Servlet的运行过程

     Servlet程序是有web服务器调用,web服务器收到客户端的Servlet请求后:

  • web服务器首先检查是否已经装在并创建了该Servlet的实例对象,如果是则直接执行第四步,否则执行第二步;
  • 装载并创建一个Servlet的实例对象;
  • 调用Servlet实例对象的init()方法;
  • 创建一个用于封装Http请求消息的HttpServletRequest对象和一个代表响应消息的HttpServletResponse对象,然后调用Servlet的service()方法,并将请求和响应对象作为参数传递进去
  • web服务器被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destory()方法。

3、在Eclipse中开发Servlet

     在eclipse中新建一个web project工程,eclipse会自动创建以下目录结构:

         

4、Servlet接口实现类

         【1】、SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet;

         【2】、HttpServlet指能够处理HTTP请求的Servlet,它在原有Servlet接口上添加了一些http协议处理方法,它比Servlet接口功能更加强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口;

         【3】、HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post方法,则调用HttpServlet的doPost方法。因此开发人员在编写Servlet时,通常只需要覆盖doGet或doPost方法,而不需要去覆盖service方法。

5、Servlet的一些细节

        【1】、由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问必须把Servlet映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

                 ·   <servlet>元素用于注册Servlet,它包含两个主要的子元素<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名;

                 ·   <servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含两个子元素<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

        示例:        <web-app>       <servlet>     <servlet-name>AnyName</servlet-name>     <servlet-class>HelloServlet</servlet-class>       </servlet>       <servlet-mapping>     <servlet-name>AnyName</servlet-name>     <url-pattern>/demo/hello.html</url-pattern>       </servlet-mapping>        </web-app>
                 注意: ①、同一个Servlet可以映射到多个URL地址上,即多个<servlet-mapping>的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。

                              ②、在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:"  *.扩展名  "、以"  /*  "结尾。

                   如:                   <servlet-mapping>                 <servlet-name>AnyName</servlet-name>                 <url-pattern>*.do</url-pattern>                   </servlet-mapping>                   <servlet-mapping>                          <servlet-name>AnyName</servlet-name>                          <url-pattern>/action/*</url-pattern>                   </servlet-mapping>
                  例题:
              对于如下的一些映射关系:                  Servlet1 映射到 /abc/*                   Servlet2 映射到 /*                   Servlet3 映射到 /abc ------------先完全匹配,再匹配通配符                  Servlet4 映射到 *.do ------------优先级最低              问题:                  当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应          <strong>----Servlet引擎将调用Servlet1。</strong>                  当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应          <strong>----Servlet引擎将调用Servlet3。</strong>                  当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应          <strong>----Servlet引擎将调用Servlet1。</strong>                  当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应         <strong> ----Servlet引擎将调用Servlet2。</strong>                  当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应          <strong>----Servlet引擎将调用Servlet2。</strong>

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

                    ·    针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是Servlet示例对象一旦创建,它就会驻留在内存中,为后续的其他请求服务,直至web服务器推出,Servlet实例对象才会销毁。

                    ·   在Servlet的整个生命周期内,Servlet的init方法只被调用一次,而对一个Servlet的每次请求都导致Servlet引擎调用一次Servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service方法,service方法再根据请求方式调用doXXX方法。

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

举例:<servlet><servlet-name>invoker</servlet-name><servlet-class>org.apache.catalina.servlets.InvokerServlet</servlet-class><load-on-startup>2</load-on-startup></servlet>
              用途:为web应用写一个InitServlet,这个Servlet为启动时装载,为整个web应用创建必要的数据库表和数据。

          【4】、如果某个Servlet映射路径仅仅为一个正斜杠,那么这个Servlet就成为当前web应用的缺省Servlet。

                    ·  凡是在 web.xml中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说缺省Servlet用于处理其他Servlet都不处理的访问请求;
                    ·   在tomcat安装路径\confg\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为缺省Servlet;

                    ·   当访问tomcat服务器中的某个静态HTML文件或图片时,实际上是在访问这个缺省Servlet。

          【5】、当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法如果访问了同一个资源的话,就有可能引发线程安全问题。

                    ·  如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式调用其service方法。

                    ·  SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可;

                    ·  对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet对象实例,并发的每个线程分别调用一个独立的Servlet实例对象;

                    ·  实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而正真意义上解决多线程问题是指一个Servlet实例对象被多个线程同时调用的问题。(事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为过时)


二、Response与Request对象

(一)、简介

      1、web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。

      2、request和response对象既然代表请求和响应,那么我们要获取客户端提交过了的数据,只需要找request对象就可以;要想客户端输送数据,只需要找response对象。

(二)、HttpServletResponse

       1、HttpServletResponse对应服务器的响应,这个对象中封装了向客户端输送数据、发送响应头,发送响应状态码的方法。

            

       2、Response常见应用

  • 想客户端输送中文数据:以outputstream和printwriter输出
  • 文件下载
  • 生成随机图片
  • 发送http头,控制浏览器定时刷新网页
  • 发送http头,控制浏览器进制缓存当前文档内容
  • 通过Response实现请求重定向:一个web资源受到客户端请求后,通知客户端去访问另一个web资源,称之为请求重定向

     3、实现方式:response.sendRedirect()

        实现原理,302状态码和location头即可实现重定向

     4、Response细节

         【1】、getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOutputStream和PrintWriter对象

         【2】、getOutputStream和getWriter这两个方法相互排斥,调用了其中的任何一个方法后,就不能调用另一个方法了。

         【3】、Servlet程序向ServletOutputStream或PrintWriter对象写入的数据,将Servlet引擎从response里面获取,Servlet引擎将这些数据当做响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。

         【4】、Servlet的service方法结束后,Servlet将检查getWriter或getOutputStream方法返回的输出流对象,是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭输出流对象。

(三)、HTTPServletRequest

     1、HttpServletRequest代表客户端的请求,当客户端通过http协议访问服务器时,http请求头中的所有信息都封装在这个对象中,开发人员通过拿到这个对象可以获取客户端的这些信息。

      2、获取客户机信息的方法:

  • getRequestURL:返回客户端发送请求时的完整URL;
  • getRequestURI:返回请求行中资源名部分;
  • getQueryString:返回请求行中的参数部分;
  • getPathInfo:返回请求URL中的额外路径信息,额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以 " / " 开头;
  • getRemoteAddr:返回发送请求的客户机IP地址;
  • getRemotHost:返回发送请求的客户机的完整主机名;
  • getRemotePort:返回客户机使用的网络端口;
  • getLocalAddr:返回web服务器的IP地址;
  • getLocalName:返回服务器的主机名;

     3、获取客户机请求头:

  • getHeader
  • getHeaders
  • getHeaderName

      4、获取客户机请求参数:

  • getParameter
  • getParameterValues(String  name)
  • getParameterNames
  • getParameterMap

      5、request常见应用

         【1】、防盗链

         【2】、各种表单输入项数据的获取

         【3】、请求参数的中文乱码问题

         【4】、JavaScript防止表单重复提交

         【5】、URL地址的编码

         【6】、request实现请求转发:

                    ·  请求转发指一个web资源受到客户端请求后,通知服务器去调用另一个web资源并进行处理。

                    ·  请求转发的应用场景:MVC设计模式

                    ·  request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发

                    ·  Request对象同时也是一个域对象,开发人员通过Request对象在实现转发时,把数据通过request对象带给其他web资源。常见方法:
                        setAttribute、getAttribute、removeAttribute、getAttributeNames

       6、请求转发的细节

  • forward方法用于将请求转发到RequestDispatcher对象封装的资源
  • 如果再调用forward方法之前,在Servlet写入的部分已经真正传送到客户端,forward方法将抛出IllegalStateException异常
  • 如果在调用forward方法之前,向Servlet引擎的缓冲区中写入了内容,只要写入到缓冲区的内容还没有真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区的内容将被清空,但是已写入到HttpServletResponse对象中响应头字段信息保持有效。

(三)、请求重定向和请求转发的区别

         1、RequestDispatcher.forward方法,只能将请求转发给同一个web应用中的组件,而HttpServletResponse.sendRedrict方法还可以重定向到同一个站点上的其他应用程序资源,甚至是绝对定向到其他站点的资源。

         2、如果传递给HttpServletResponse.sendRedirect方法的相对URL以/开头,它是相对于整个web站点的根目录,如果创建RequestDispatcher对象指定相对/路径开头,他是相对web应用的根目录。

         3、调用HttpServletResponse.sendRedirect方法重定向的过程结束后,浏览器地址栏中显示的的RUL会发生变化,由初始URL地址变成重定向的目标URL地址,调用RequestDispatcher.forward方法请求转发过程结束,浏览器地址栏保持初始URL不变。

         4、HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器重新发出对另一个URL的访问请求,RequestDispatcher.forward方法在服务器端内部将请求转发给另一个资源,浏览器只发出了请求并得到了响应结果,并不知道服务器内部发生了转发行为。

         5、RequestDispatcher.forward方法的调用者和被调用者之间共享相同的Request对象和Response对象,他们属于同一个请求和响应过程,而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。


三、ServletConfig与ServletContext对象

1、ServletConfig

     【1】在Servlet的配置文件中,可以使用一个或多个<inint-param>标签为Servlet配置一些初始化参数;

     【2】当Servlet配置了初始化参数后,web容器在创建Servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用Servlet的init方法时,将ServletConfig对象传递给Servlet对象。进而,程序员通过ServletConfig对象就可以得到当前Servlet的初始化参数。

2、ServletContext

     【1】web容器在启动时,他会为每一个web应用程序创建一个对应的ServletContext对象,它代表当前web应用;

     【2】ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写Servlet时,可以通过ServletConfig.getServletContext方法获取ServletContext对象;

     【3】由于一个web应用中,所有的Servlet共享一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通信。ServletContext对象通常也被称为context域对象。

     【4】ServletContext对象的应用

  • 多个Servlet通过ServletContext对象实现数据共享;
  • 获取web应用的初始化参数;
  • 实现Servlet的转发;
  • 利用ServletContext对象读取资源文件;

                ·      得到文件路径;

                ·      读取资源文件的三种方式

                ·       .properties文件(属性文件) 


三、会话管理


(一)、会话

          1、什么是会话?

                可以简单的理解为,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

           2、会话过程中要解决的一些问题?

                ·  每个用户在使用浏览器与服务器进行会话的过程中,不可避免的各自会产生一些数据,程序要想办法为每个用户保存这些数据;

                ·  例如:用户点击超链接通过一个Servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结账Servlet时,结账Servlet可以得到用户购买的商品为用户结账;

                ·  思考:用户购买的商品保存在request或ServletContext中行不行?

(二)、保存会话数据的两种技术:

         1、Cookie

           【1】、简介

                 Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给各自的浏览器,当用户使用浏览器再去访问服务器中的web资源时,就会带各自的数据去,这样web资源处理的就是用户各自的数据了。

                  

           【2】、Cookie API

                javax.servlet.http.Cookie类用于创建一个Cookie,response接口中也定义了一个addCookie方法,它用于在其响应头中增加一个Set-Cookie头字段。同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法有:

  • public Cookie(String name,String value)
  • setValue与getValue方法
  • setMaxAge与getMaxAge方法
  • setPath与getPath方法   /day06
  • setDomain与getDomain方法
  • getName方法

          【3】、Cookie细节

  • 一个cookie只能标识一种信息,他至少含有标识该信息的名称和设置值;
  • 一个web站点可以给一个web浏览器发送多个Cookie,一个web浏览器也可以存储多个web站点提供的cookie;
  • 浏览器一般只允许存储300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4k;
  • 如果创建了一个Cookie,并将它发送给浏览器,默认情况下他是一个会话级别的Cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该Cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间,将最大时效设为0则是命令浏览器删除该cookie


          2、Session

                   Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个浏览器的用户创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器web资源时,其他web资源再从用户各自的session中取出数据为用户服务。



       【1】、在web开发中,服务器为每个用户创建一个会话对象,一个浏览器独占一个Session对象,因此在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器毒战的session中,当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出数据,为用户服务。

       【2】、Session和Cookie的主要区别,Cookie把用户的数据写给用户的浏览器,Session把用户的数据写到用户独占的session中

       【3】、Session对象由服务器创建,开发人员可以调用request对象getSession方法得到session对象。

0 0