JavaWeb开发

  • XML基础
  • 用tomcat构建web站点
    • WEB开发的相关知识
      • lInternet上供外界访问的Web资源分为
        • 静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变。
        • 动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。
          • 常用动态web资源开发技术:JSP/Servlet、ASP、PHP等
      • JAVAEE规范
        • SUN公司制定的规范。
        • 包含13种技术,JSP/Servlet是其中的一种。
      • 常见WEB服务器
        • WebLogic是BEA公司的产品,是目前应用最广泛的Web服务器,支持JavaEE规范,而且不断的完善以适应新的开发要求。收费。
        • IBM公司的WebSphereAS,支持JavaEE规范。
        • 大名鼎鼎的红帽的产品,原来属于开源组织JbossAS,后被红帽收购。支持JavaEE规范,免费。
        • 在小型的应用系统或者有特殊需要的系统中,可以使用一个 免费的Web服务器:Tomcat,该服务器支持全部JSP以及 Servlet规范。
        • Tomcat属于轻量级的服务器。其它服务器属于重量级的服务器。
      • 服务器规范和应用的三角关系

        • 应用程序按照JavaEE规范开发,与具体运行在哪个服务器上无关。
    • Tomcat服务器简介
      • Tomcat是在SUN公司推出的小型Servlet/JSP调试工具的基础上发展起来的一个优秀的Servlet容器,Tomcat本身完全用Java语言编写。
      • 目前是Apache开源软件组织的一个软件项目,它的官方网址为http://tomcat.apache.org。
      • 得到了广大开源代码志愿者的大力支持,且可以和目前大部分的主流Web服务器(IIS、Apache服务器)一起工作,它运行稳定、可靠且高效。
      • 已成为目前开发企业JavaWeb应用的最佳Servlet容器选择之一。
      • 获取Tomcat安装程序包:
        • tar.gz文件是Linux操作系统下的安装版本
        • exe文件是Windows系统下的安装版本x86 x64
        • zip文件是Windows系统下的压缩版本 (建议)
      • Tomcat的版本:
        • Tomcat的版本随着SUN公司推出的Servlet/JSP规范不同而不同,基本上是SUN公司每推出一个版本,Tomcat也会发行新的版本以适应新的规范。

    • 安装Tomcat
      • 在安装和使用Tomcat之前必须先行安装相应版本的JDK(JRE)。
      • 解压对应的包(请不要解压到中文目录或有空格的目录中)。
      • Tomcat的安装目录称之为CATALINA_HOME。
      • 启动:进入\bin,执行startup.bat启动Tomcat。
      • 验证是否启动成功:http://localhost:8080,如果看到页面,表示成功了。
      • 安装中可能遇到的问题:
        • Java_home环境变量:
          • 必须配置JAVA_HOME环境变量,指向JDK的安装目录。
        • 端口占用问题(更改默认端口):
          • Tomcat使用的默认端口是8080.Web中HTTP默认使用的端口是80(HTTP协议规定的80端口)。
          • 更改Tomcat使用的默认端口8080---->8888:
            • 找到\conf\server.xml文件
            •                connectionTimeout="20000" 
                             redirectPort="8443" />
        • Catalina_home环境变量的设置问题
          • 不建议配置CATALINA_HOME环境变量。
    • Tomcat的目录结构(服务器厂商自己安排的)
      • bin:存放启动和关闭Tomcat的一些批处理命令。如startup.bat和shutdown.bat等。
      • conf:存放Tomcat的配置文件(全局)。
      • lib:Tomcat运行用到的jar包(全局)。
      • logs:Tomcat的启动和运行日志。
      • temp:存放临时文件。
      • webapps:存放JavaWeb应用的目录。(该目录中有几个目录--不含子目录,就说明当前Tomcat管理者几个应用)。
      • work:Tomcat的工作目录。
    • JavaWeb的目录结构(SUN公司的Servlet规范要求的)
      • 一个web应用由多个静态web资源和动态web资源组成。
      • 开发web应用时,不同类型的文件有严格的存放规则,否则不仅可能会使web应用无法访问,还会导致web服务器启动报错。

      • WEB-INF:必须有。此目录中的资源文件用户无法直接访问到。
        • classes:存放编译后的class文件。
        • lib:存放应用需要的jar包。
        • web.xml:当前应用的配置文件。
    • 如何部署JavaWeb应用
      • 开放式目录:把应用直接拷贝到Tomcat\webapps目录下即可。
      • 把应用打成war:进入应用的根目录,执行jar -cvf MyApp.war,将应用打成war包,把war包拷贝到Tomcat\webapps目录下即可。
    • Tomcat的核心组成部分
      • Tomcat本身由一系列可配置的组件构成,其中核心组件是Servelt容器组件,它是所有其他Tomcat组件的顶层容器。
      • 每个组件都可以在Tomcat安装目录/conf/server.xml文件中进行配置,每个Tomcat组件在server.xml文件中对应一种配置元素。
      • 以下用XML的形式展示了各种Tomcat组件之间的关系:

      • server.xml是Tomcat的核心配置文件。
      • Context:用于配置某个应用。
      • Host:用于配置某个主机。
      • Tomcat体系架构:
    • 配置Web站点的虚拟目录:Context
      • 方式一:在server.xml文件的host元素中配置,例如:
        • Context元素必须出现在Host元素的内部。
        • path:指定虚拟目录。以"/"开头。
        • docBase:指定实际的应用的目录地址。
        • 不建议使用,需要重新启动Tomcat。
      • 方式二:在Tomcat\conf\[enginename]\[hostname]目录下建立一个扩展名为xml的配置文件,内容如下:

        • 此处:文件名就是虚拟目录的名字(等同于path的功能),其他不变。
        • 此种方式不需要重新启动Tomcat就可以生效。
      • 小练习:配置默认端口、默认应用、默认主页。
        1. 修改默认端口:修改server.xml中的那个8080为80。
        2. 更改默认应用:在Tomcat\conf\[enginename]\[hostname]目录下建立一个扩展名为ROOT.xml的配置文件(不重启无效),内容如下:


        3. 在应用的WEB-INF目录下,建立一个web.xml的配置文件,内容如下:



              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
              version="2.5">
             
                  b.html
             




      • Tomcat6.x提供了多种配置元素的途径。当其加载一个web应用时,会依次按照以下五种方式尝试查找Web应用的元素,直到找到为止:
        1. 到Tomcat安装目录/conf/context.xml文件中查找元素。
        2. 到Tomcat安装目录/conf/[enginename]/[hostname]/context.xml.default文件中查找元素。
        3. 到Tomcat安装目录/conf/[enginename]/[hostname]/[contextpath].xml文件中查找元素。
          • [contextpath]:表示单个Web应用的URL入口。
        4. 到Web应用的META-INF/context.xml文件中查找元素。
        5. 到Tomcat安装目录/conf/server.xml文件中查找元素。只适用于单个Web应用。
        • 如果仅仅为单个Web应用配置元素,可以优先采用第三种配置方式。
      • Context元素的属性

        • 在一般情况下,元素都会使用默认的标准Context组件,即className属性采用默认值org.apache.catalina.core.StandardContext,它除了拥有上面介绍到的属性外,还有自身专有的属性:
          • cachingAllowed是否允许启用静态资源(HTML、图片、声音等)的缓存。默认值为true。
          • cacheMaxSize设置静态资源缓存的最大值,单位为K。
          • workDir指定Web应用的工作目录。
          • uppackWAR如果为true,会把war文件展开为开放目录后再运行。为false,直接运行war文件。默认值为true。
      • web.xml文件
        • 通过web.xml文件,可以将web应用中的:
          • 某个web资源配置为网站首页
          • 将servlet程序映射到某个url地址上
          • ……
        • 但凡涉及到对web资源进行配置,都需要通过web.xml文件。
        • 举例:通过web.xml文件配置网站首页。
        • 注意:web.xml文件必须放在web应用\WEB-INF目录下。
    • 配置Web站点的虚拟主机:Host
      • 假如两家公司Web应用都发布在同一个Tomcat服务器上,可以为每家公司分别创建一个虚拟主机。
      • 尽管以上两个虚拟主机位于同一个主机,但是当客户通过以上两个不同虚拟主机名访问Web应用时,会感觉到这两个应用分别拥有独立的主机。
      • 如需在WEB服务器中配置一个网站,需在server.xml中使用Host元素进行配置,例:
        • name:主机的名称。
        • appBase:本主机下的所有应用的存放目录。
      • 配置的主机(网站)要想被外部访问,必须在DNS服务器或windows系统中注册。
    • 链接器:Connector
      • Tomcat与其他服务器整合原理图:

    • 在Tomcat中配置SSL
      • 在网络上,信息在由源主机到目标主机的传输过程会经过其他计算机,网络上的信息有可能被非法分子监听,从而导致个人隐私泄露。
      • 随着电子商务的发展,对信息安全的要求越来越高,于是Netscape公司提出了SSL(Server Socket Layer)协议,旨在达到在开放网络(Internet)上安全、保密地传输信息的目的。
      • HTTPS=HTTP+SSL。HTTPS使用的默认端口是443。SSL是一种保证网络上的两个节点进行安全通信的协议,建立在SSL协议上的HTTP被称为HTTPS协议。
      • SSL采用加密技术来实现安全通信,保证通信数据的保密性和完整性,并且保证通信双方可以验证对方的身份。
      • 加密技术的基本原理是:
        • 数据从一端发送到另一端,发送者先对数据加密,然后再把它发送给接受者。
        • 这样,在网络上传输的是经过加密的数据,如果有人非法截获了这批数据,由于没有解密的密钥,就无法获得真正的原始数据。
        • 接收者收到加密的数据后,先对数据解密,然后再处理。
      • SSL通过安全证书来证明客户或服务器的身份。当客户通过安全的连接和服务器通信时,服务器会先向客户出示它的安全证书,而每一个证书在世界范围内都是唯一的。为了扩大用户群,一些服务器向客户出示证书后,并不要求客户出示安全证书,但在某些情况下,服务器也会要求客户出示安全证书,以便核实该客户的身份。
      • 安全证书的获得有两种方式:
        • 从权威机构获得证书
          • Certificate Authority,CA和VeriSign和Thawte,它们保证了证书的可信性。申请证书时,需要付费,且一个证书只针对一个IP有效。
        • 创建自我签名的证书
          • 如果只关心数据在网络上的安全传输,而不需要对方身份验证,可以创建自我签名的证书。与权威机构颁发的证书采用的加密技术是一样的。
      • 可以根据安全需要,为Tomcat配置SSL,它包含以下两个步骤:
        1. 准备安全证书
          • 创建自我签名的证书。
          • SUN公司提供了制作证书的工具keytool。在JDK1.4以上版本中都包含了这一工具。通过这个工具生成证书的命令为:
            keytool -genkey -alias tomcat -keyalg RSA
            以上命令将生成包含一对非对称密钥和自我签名的证书,这个命令中参数的意思
            -genkey:生成一对非对称密钥。
            -alias:指定密钥对的别名,该别名是公开的。
            -keyalg:指定加密算法,此处采用通用的RSA算法。
          • 以上命令将在操作系统的用户目录下生成名为”.keystore”的文件。
          • 如果希望生成的keystore文件放在其他目录中,可以使用-keystore参数
            keytool -genkey -alias tomcat -keyalg RSA -keystore d:\.keystore
        2. 配置Tomcat的SSL连接器(Connector)
          • 在Tomcat的servlet.xml文件中,已经提供了现成的配置SSL连接器的代码,只要把注释去掉即可
                           maxThreads="150" scheme="https" secure="true"
                           clientAuth="false" sslProtocol="TLS" />
          • 其他属性:
            keystoreFile:指定keystore文件的存放位置,可以指定绝对路经。如果此项没有设定,在默认情况下,Tomcat将从当前操作系统用户的用户名目录下读取名为”.keystore”的文件。
            keystorePass:指定keystore的密码,如果此项没有设定,在默认情况下,Tomcat将使用”changeit”密码。
          • 错误:
            • 在配置tomcat的SSL双向握手中,由于6.0.33版本中默认启用了APR(APR是通过JNI访问的可移植库,可以提高Tomcat的性能和伸缩性),所以采用传统的配置方式(如下)会报异常:

      • 访问支持SSL的Web站点:https://localhost:8443
      • 当Tomcat接收到这一HTTPS请求后,会向客户的浏览器发送服务器的安全证书,IE浏览器接收到证书后,将向客户显示安全警报。
  • HTTP协议详解
    • HTTP协议概述
      • WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个规则就是HTTP协议。
      • HTTP是HyperText Transfer Protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程及数据本身的格式。
      • HTTP协议的版本:
        • HTTP/1.0:无状态协议。
          • 基于HTTP协议的客户/服务器模式的信息交换过程,如图所示,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。

          • 浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。
          • 浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应。
        • HTTP/1.1:有状态协议。一次连接基础上可以发出多次请求和响应。
          • 在一个TCP连接上可以传送多个HTTP请求和响应。
          • 多个请求和响应过程可以重叠
          • 增加了更多的请求头和响应头,比如Host、If-Unmodified-Since请求头等。

      • 浏览器访问多图网页:
        • 在一个HTML页面中如果包含标记的话,当浏览器解析到这些标记时,还会向服务器请求访问标记中指定的文件,即再次建立连接并发出HTTP请求。
        • 如果HTML页面中有一个超级链接:itcast,当点击这个链接时,也会触发浏览器与Web服务器开始一次新的HTTP通信。

    • HTTP消息格式
      • HTTP请求消息
        • 客户端连上服务器后,向服务器请求某个web资源,称之为客户端向服务器发送了一个HTTP请求。
        • Web服务器通过客户端发送过来的这些请求信息,就可以确定向请求者回送什么资源,以及根据客户端的环境信息采用什么方式进行回送等。
        • 一个完整的HTTP请求包括如下内容:
          • 一个请求行、若干消息头、以及请求正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用空行隔开。
        • 举例:
      • HTTP响应消息
        • 一个HTTP响应代表服务器向客户端回送的数据。
        • 在一个HTTP响应中,WEB服务器通过响应头向web客户端描述客户端的请求成功与否,以及它所发送的数据类型等一些信息,客户端通过这些信息,进而可以知道如何对数据进行处理。
        • 一个完整的HTTP响应包括如下内容:
          • 一个状态行、若干消息头、以及响应正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用空行隔开。
        • 举例:
    • HTTP请求行
      • 格式:请求方式 资源路径 HTTP版本号
      • 举例:GET /temp3o116.shtml HTTP/1.1
      • 请求方式:GET、POS、HEAD、OPTIONS、DELETE、TRACE、PUT
      • 用户如没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点超链接访问等都是get,用户如想把请求方式改为post,可通过更改表单的提交方式实现。
      • 不管POST或GET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上。
      • GET方式
        • 如请求方式为GET方式,则可以在请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如:
          GET /mail/1.html?name=abc&password=xyz HTTP/1.1
        • GET方式的特点:
          • 在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。
          • 请求参数会出现在地址栏上,不安全。
      • POST方式
        • 如请求方式为POST方式,则可以在请求的正文内容中向服务器发送数据。
        • Post方式的特点:
          • 传送的数据量无限制。
          • 请求参数会出现在正文部分,安全。
    • HTTP响应行
      • 格式: HTTP版本号 状态码 原因叙述
      • 举例:HTTP/1.1 200 OK
      • 状态码用于表示服务器对请求的各种不同处理结果和状态,它是一个三位的十进制数。
      • 响应状态码分为5类,使用最高位为1到5来进行分类如下所示:

      • 常用状态码:
        • 200(正常)
          表示一切正常,返回的是正常请求结果
        • 302/307(临时重定向)
          指出被请求的文档已被临时移动到别处,此文档的新的URL在Location响应头中给出。
        • 304(未修改)
          表示客户机缓存的版本是最新的,客户机可以继续使用它,无需到服务器请求。
        • 404(找不到)
          服务器上不存在客户机所请求的资源。
        • 500(服务器内部错误)
          服务器端的程序发生错误
    • HTTP消息头(请求和响应共性)
      • 使用消息头,可以实现HTTP客户机与服务器之间的条件请求和应答,消息头相当于服务器和浏览器之间的一些暗号指令。
      • 每个消息头包含一个头字段名称,然后依次是冒号、空格、值、回车和换行符
        如: Accept-Encoding: gzip, deflate
      • 消息头字段名是不区分大小写的,但习惯上讲每个单词的第一个字母大写。
      • 整个消息头部分中的各行消息头可按任何顺序排列。
      • 消息头又可分为通用信息头、请求头、响应头、实体头等四类。
      • 许多请求头字段都允许客户端在值部分指定多个可接受的选项,多个选项之间以逗号分隔。
      • 有些头字段可以出现多次,例如,响应消息中可以包含有多个”Warning”头字段。
    • HTTP常用请求头
      • 请求头字段用于客户端在请求消息中向服务器传递附加信息,主要包括客户端可以接受的数据类型(MIME类型)、压缩方法、语言以及发出请求的超链接所属页面的URL地址等信息。
      • 常用请求头:
        • Accept:浏览器可接受的MIME类型 (Tomcat\conf\web.xml记载着文件系统的文件扩展名和MIME类型的对应关系)
        • Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
        • Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip 
        • Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。 可以在浏览器中进行设置。
        • Host:初始URL中的主机和端口 
        • Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。作用:防盗链;广告投放效果。
        • Content-Type:application/x-www-form-urlencoded  内容类型。只有表单时,且method为post时有效。效果等同于form表单的属性enctype="application/x-www-form-urlencoded"
        • If-Modified-Since:Wed, 02 Feb 2011 12:04:56 GMT   利用这个头与服务器的文件进行比对,如果一致,则从缓存中直接读取文件。
        • User-Agent:浏览器类型.
        • Content-Length:表示请求消息正文的长度 
        • Connection:表示是否需要持久连接。如果服务器看到这里的值为“Keep -Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接 ),则持久连接。
        • Cookie:这是最重要的请求头信息之一 
        • Date:Date: Mon, 22 Aug 2011 01:55:39 GMT  请求时间GMT
    • HTTP常用响应头
      • 响应头字段用于向客户端传递附加信息。
      • 常用响应头:
        • Location:http://www.it315.org/index.jsp 指示新的资源的位置。结合302或307响应码来使用,完成请求重定向。
        • Server:apache tomcat指示服务器的类型
        • Content-Encoding: gzip 服务器发送的数据采用的编码类型
        • Content-Length:80 告诉浏览器正文的长度
        • Content-Language: zh-cn服务发送的文本的语言
        • Content-Type::text/html; charset=GB2312服务器发送的内容的MIME类型
        • Last-Modified:Tue, 11 Jul 2000 18:23:51 GMT文件的最后修改时间
        • Refresh: 1;url=http://www.it315.org指示客户端刷新频率。单位为秒。默认刷新自己。
          刷新到别的资源:3;URL=/day04/1.html
        • Content-Disposition: attachment; filename=aaa.zip指示客户端下载文件
        • Set-Cookie:SS=Q0=5Lb_nQ; path=/search服务器端发送的Cookie
        • Expires: -1  毫秒值,控制缓存的时间
        • Cache-Control: no-cache (1.1)  
        • Pragma: no-cache   (1.0)  以上三个头控制资源不要缓存
        • Connection: close/Keep-Alive   
        • Date: Tue, 11 Jul 2000 18:23:51 GMT
  • Servlet开发基础
    • Servlet概述
      • Servlet是sun公司提供的一门用于开发动态web资源的技术。
      • Sun公司在其API中提供了一个servlet接口,用户若想开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
        • 编写一个Java类,实现servlet接口。
        • 把开发好的Java类部署到web服务器中。
    • Servlet接口
      • javax.servlet.Servlet接口:任何的Servlet必须实现的接口(被容器调用)
      • void init(ServletConfig config):初始化一个Servlet时会被调用
      • void service(ServletRequest req,ServletResponse resp):针对用户的每一次请求,此方法都会被调用
      • void destroy():当一个Servlet对象被摧毁时,调用该方法。
    • Servlet的编写步骤
      1. 建立标准的javaWeb应用目录结构
        FirstApp
        WEB-INF
        classes
        lib
        web.xml
      2. 在classes目录下建立一个类,直接或间接的实现Servlet这个接口
        package com.itheima;
        import java.io.*;
        import javax.servlet.*;
        
        public class HelloServlet extends GenericServlet{
        	public void service(ServletRequest req,
                                     ServletResponse res)
                              throws ServletException,
                                     IOException{
        		String data = "hello servlet";					 
        		ServletOutputStream sos = res.getOutputStream();
        		sos.write(data.getBytes());
        		sos.close();
        	}
        
        }

      3. 3、编译java源文件(编译前把servlet-api.jar 加入到classpath中)
        set classpath=%classpath%;C:\apache-tomcat-6.0.35\lib\servlet-api.jar
        进入到classes目录中,执行以下语句进行编译:
        javac -d . HelloServlet.java
      4. 修改web.xml,对servlet进行URL映射
        
        
        
        
        	
        		HelloServlet
        		com.itheima.HelloServlet
        	
        	
        		HelloServlet
        		/hello
        	
        

      5. 访问该Servlet的地址是:http://localhost:8080/FirstApp/hello
    • Servlet的执行过程
      1. 客户端发出请求http://localhost:8080/Demo1/hello
      2. 根据web.xml文件的配置,找到子元素的值为“/hello”的元素
      3. 读取元素的子元素的值,由此确定Servlet的名字为”HelloServlet”
      4. 找到值为HelloServlet的元素
      5. 读取元素的子元素的值,由此确定Servlet的类名为cn.itcast.HelloServlet。
      6. 到Tomcat安装目录/webapps/Demo1/WEB-INF/classes/cn/itcast目录下查找到HelloServlet.class文件
    • Servlet的执行过程图解

      • Tomcat在加载Web应用时,就会把相应的web.xml文件中的数据读入到内存中。因此当Tomcat需要参考web.xml文件时,实际上只需要从内存中读取相关数据就可以了,无需再到文件系统中读取web.xml。
    • Servlet的运行过程
      • Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
        1. Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
        2. 装载并创建该Servlet的一个实例对象。
        3. 调用Servlet实例对象的init()方法。
        4. 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
        5. WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
      • Servlet的运行过程示意图:







    • Servlet的生命周期
      • Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
      • 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
      • 在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。 
      • 默认情况下:只有第一次访问Servlet对象时,才会被实例化,并调用init方法。
      • 当应用被卸载或者Tomcat被关掉时,才会调用destroy方法,释放Servlet占用的资源。
      • 针对用户的每一次请求,服务器都会采用线程的机制调用service方法。
      • 如果在元素中配置了一个元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。举例:
        
        	invoker
        	
        		org.apache.catalina.servlets.InvokerServlet
        	
        	2
        
        用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。
      • 从提高Servlet容器运行性能的角度出发,Servlet规范为Servlet规定了不同的初始化情形。如果有些Servlet专门负责在web应用启动阶段为web应用完成一些初始化操作,则可以让它们在web应用启动时就被初始化。对于大多数Servlet,只需当客户端首次请求访问时才被初始化。假设所有的Servlet都在web应用启动时被初始化,那么会大大增加Servlet容器启动web应用的负担,而且Servlet容器有可能加载一些永远不会被客户访问的Servlet,白白浪费容器的资源。
    • 在Eclipse中开发Servlet

    • Servlet API介绍
      • SUN公司定义了一套专门用于开发Servlet程序的Java类和接口,它们统称为Servlet API。
      • Servlet引擎与Servlet程序之间采用Servlet API进行通信。
      • 一个Servlet程序就是一个在服务器端运行的调用了Servlet API的Java类。
      • Servlet规范的类包:
        • javax.servlet:存放的接口、抽象类与具体协议无关
        • javax.servlet.http:存放的接口、抽象类与HTTP协议有关
      • Servlet API中提供了一个实现了Servlet接口的最简单的Servlet类,其完整名称为javax.servlet.GenericServlet。
      • Servlet API中还提供了一个专用于HTTP协议的Servlet类,其名称是javax.servlet.http.HttpServlet,它是GenericServlet的子类。
      • 我们编写的Servlet程序通常只需要覆盖service方法即可。
      • 对于继承HttpServlet的子类,不应该覆盖掉其中service方法。HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
    • Servlet的一些细节
      • 同一个Servlet可以被映射到多个URL上,即多个元素的子元素的设置值可以是同一个Servlet的注册名。 
      • 在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
      • 例如:
        
        	
        		AnyName
        	
        	
        		*.do
        	
        
        
        
        	
        		AnyName
        	
        	
        		/action/*
        	
        

      • 对于如下的一些映射关系:
        Servlet1 映射到 /abc/* 
        Servlet2 映射到 /* 
        Servlet3 映射到 /abc 
        Servlet4 映射到 *.do 
        问题:
        当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
        Servlet引擎将调用Servlet1。
        当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
        Servlet引擎将调用Servlet3。
        当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
        Servlet引擎将调用Servlet1。
        当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
        Servlet引擎将调用Servlet2。
        当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
        Servlet引擎将调用Servlet2。
      • 路径匹配多个Servlet映射时:
        绝对匹配优先于通配符
        都是用通配符时,/开头的优先级高
        都是用通配符时,都以/开头又有多个匹配:从前往后开始匹配
      • 如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。 
      • 凡是在web.xml文件中找不到匹配的元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。 
      • \conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。
      • 当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。 服务器中的html文件数据的读取由缺省servlet完成。
    • 修改MyEclipse自动生成的Servlet的模板
      • 关闭MyEclipse。
      • 找到MyEclipse的安装目录。
      • 搜索*wizard*,找到com.genuitec.eclipse.wizards_8.5.0.me201003052220.jar。
      • 打开,找到templates\Servlet.java,此文件就是模板文件。
      • (修改前先备份)修改该文件,再放回去。
    • ServletConfig接口
      • 在Servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数。例如:
        
            ServletDemo3
            com.itheima.servlet.ServletDemo3
            
            	encoding
            	UTF-8
            
        	
            	aaa
            	yyy
            
            2
        

      • 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
      • ServletConfig:代表了针对当前Servlet的配置参数init-param中配置的参数。
      • 常用的方法:
        • String getInitParameter(String paramName):获取指定参数名称的取值
        • Enumeration getInitParameterNames():获取所有的参数的名称
        • String getServletName():返回当前Servlet实例的名称
    • 线程安全问题
      • 尽量使用局部变量。
    • ServletContext接口
      • WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
      • ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。或者直接通过getServletContext方法获得ServletContext对象。
      • 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。
      • ServletContext对象通常也被称之为context域对象。
      • 域对象内部维护了一个Map。
      • ServletContext应用:
        • 多个Servlet通过ServletContext对象实现数据共享。
        • 获取WEB应用的初始化参数。
          • 对于web.xml文件中的参数:
            
            	encoding
            	UTF-8
            
          • 可以使用下面的方法获取参数:String getInitParameter(String paramName)
            Enumeration getInitParameterNames()
        • 实现Servlet的转发。
          • RequestDispatcher getRequestDispatcher(String path):path:目标的地址。该地址必须以"/"开头,此"/"就代表当前的应用
          • RequestDispatcher.forward(request,response);
        • 利用ServletContext对象读取资源文件。
          • 资源文件通常有两种方式:
            • 对于简单的资源文件,即包含key=value的形式,我们一般采用properties,这些文件的扩展名一般为*.properties。
            • 对于较复杂的资源文件,采用XML格式。
          • 读取资源文件的三种方式:
            1. ResourceBundle:
              • 特点:只能读取properties的配置文件。且只能读取类路径下的配置文件。
                    可以在非Web环境下使用。
            2. ServletContext:
              • getRealPath(String path):path资源的路径。该地址必须以"/"开头,此"/"就代表当前的应用,返回在磁盘上的实际绝对路径。
              • 特点:读取任何位置上的任何文件。
                    只能在web环境下使用。
            3. ClassLoader:
              • 特点:只能读取类路径下的配置文件。且可以加载任何的资源。
  • Servlet规范中核心接口类图

  • HttpServletResponse与HttpServletRequest
    • HttpServletResponse
      • HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
      • 向客户端输出中文数据的问题:
        • 用OutputStream(字节流)发送数据:
          • response.getOutputStream().write(“中国”.getBytes());//以默认编码发送数据
            response.getOutputStream().write("中国".getBytes("UTF-8"));//以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码
          • 解决办法:
            1. 通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取)
            2. 通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码
            3. 通过meta标签模拟请求头:out.write("".getBytes());
            4. 通过以下方法:response.setContentType("text/html;charset=UTF-8");
          • 总结:程序以什么编码输出,就需要告知客户端以什么编码显示。
        • 用PrintWriter(字符流)发送数据:
          • response.getWriter().write(“中国” );以默认编码发送数据 ISO-8859-1(没有中国二字编码),此时会发生乱码
          • 解决办法:
            • setCharacterEncoding(“UTF-8”);//更改编码为UTF-8
              response.setHead(“Context-type”,”text/html;charset=UTF-8”);//告诉客户端编码方式
            • 注意:不要忘记告诉客户端的编码方式。
            • 由于经常改动编码,response提供了一种更简单的方式
              response. setContentType(“text/html;charset=UTF-8”);其作用相当于以上两条代码。
      • response常见应用:
        • 文件下载

          • 问题:中文文件名乱码或无法下载
          • 解决:将文件名进行编码

        • 输出随机图片

        • 发送http头,控制浏览器定时刷新网页
        • 通过response实现请求重定向。
          • 请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
          • 地址栏会变,并发送2次请求,增加服务器负担。
          • 实现方式:
            response.sendRedirect()
          • 实现原理:
            302/307状态码和location头即可实现重定向。
      • response细节
        • getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常。
        • Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。 
        • Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。 
    • HttpServletRequest
      • HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
      • request常用方法:
        • 获得客户机信息:
          • getRequestURL方法返回客户端发出请求时的完整URL。
          • getRequestURI方法返回请求行中的资源名部分。
          • getQueryString 方法返回请求行中的参数部分。
          • getRemoteAddr方法返回发出请求的客户机的IP地址。
          • getRemoteHost方法返回发出请求的客户机的完整主机名。
          • getRemotePort方法返回客户机所使用的网络端口号。
          • getLocalAddr方法返回WEB服务器的IP地址。
          • getLocalName方法返回WEB服务器的主机名。
          • getMethod得到客户机请求方式。
        • 获得客户机请求头:
          • getHead(name)方法 
          • getHeaders(String name)方法 
          • getHeaderNames方法 
        • 获得客户机请求参数(客户端提交的数据):
          • getParameter(name)方法
          • getParameterValues(String name)方法
          • getParameterNames方法 
          • getParameterMap方法  //做框架用,非常实用
          • getInputStream
      • request常见应用:
        • 各种表单输入项数据的获取
        • 请求参数的中文乱码问题
          • 客户端提交的请求参数:客户端当前使用什么编码,就以什么编码给你的程序传递数据。
            客户用的页面用的编码,可以通过meta去指定。(建议使用UTF-8)
          • 程序中打印的乱码问题:程序不知道你传递的数据编码方式。
          • request.setCharacterEncoding("UTF-8")通知服务器程序,客户端提交的数据查询的是UTF-8码表。只能解决POST请求方式提交的数据。
          • get提交方式,查ISO-8859-1
            解决办法:得到字符的原始字节序列,用UTF-8重新编码。new String(name.getBytes("ISO-8859-1","UTF-8"));
  • JSP
    • JSP概述
      • JSP:Java Server Pages
      • JSP是简化Servlet编写的一种技术,它将Java代码和html语句混合在同一个文件中编写,只对网页中要动态产生的内容采用Java代码来编写,而对固定不变的静态内容采用普通静态html页面的方式编写。
      • JSP页面是由html语句和嵌套在其中的java代码组成的一个普通文本文件,扩展名为.jsp。
      • JSP中的java 代码需要嵌套在<%和%>中,嵌套在<%和%>中的内容称之为脚本片段(Scriptlets),没有嵌套在<%和%>中的内容称之为JSP的模板元素。
      • 脚本片段被当做java程序代码被解释执行,模板元素则被原封不动地输出给浏览器。
      • JSP文件像普通的HTML文件一样,可以放置在Web应用程序中的除了WEB-INF及其子目录外的其他任何目录中。
    • JSP程序举例
      • simple.jsp文件
        <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
        <%
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
        %>
        
        
        
          
            
            
            My JSP 'Simple.jsp' starting page
            
        	
        	
        	    
        	
        	
        	
        
          
          
          
          	current time is 
            <%
            	String currentTime = new Date().toString();
            	out.println(currentTime);
             %>
          
        
        网页运行结果:


    • JSP的运行原理
      • 每个JSP页面在第一次被访问时,JSP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的class类文件,然后再由Web容器像调用普通Servlet程序一样的方式来装载和解释执行这个Servlet程序。
      • 如果在翻译或者编译的过程中出现了任何错误,JSP引擎将中断翻译或编译过程,并将错误的详细信息发送给客户端。
      • JSP页面所创建的Servlet源文件和class类文件放置在\work\Cataina\localhost\应用 这个目录下。
      • 一个JSP页面只在第一次被访问时,才需要被翻译成Servlet程序,对于该JSP页面的后续访问,Web容器将直接调用其翻译成的Servlet程序。
      • 在JSP页面每次被访问时,JSP引擎默认都会检查该JSP文件和编译成的Servlet类的最后更改时间,如果JSP文件发生了修改,JSP引擎将重新编译该JSP文件。
      • 由simple.jsp生成的Servlet类名为simple_jsp,simple_jsp继承了org.apache.jasper.runtime.HttpJspBase类。HttpJspBase类是HttpServlet的一个子类,因此simple.jsp生成的类是HttpServlet的一个孙子类。显然,simple_jsp类就是一个Servlet。
      • HttpJspBase类的init方法内部调用了jspInit和_jspInit这两个方法,HttpJspBase类的destroy方法内部调用了jspDestroy和_jspDestroy这两个方法。其中,init方法和destroy方法被final修饰,不能被覆盖。通常覆盖jspInit和jspDestroy方法来完成初始化和清尾的工作。
      • HttpJspBase类的service方法内仅仅是调用了_jspService方法,所以可以认为_jspService方法的作用就相当于HttpServlet类的service方法。
      • Tips:out.print语句与out.write语句的区别:
        • 如果字符串对象的值为null,print方法将输出内容为"null"的字符串,而write方法则是抛出NullPointerException异常。
    • JSP最佳实践
      • 不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。
      • 其原因为,程序的数据通常要美化后再输出:
        让JSP既用java代码产生动态数据,又做美化会导致页面难以维护。
        让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。
      • 因此最好的办法就是根据这两门技术的特点,让它们各自负责各得,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。
    • JSP基本语法
      • JSP页面中可以包含模板元素、脚本元素、指令、EL(Expression Language)表达式、行为元素和注释等内容。
      • 有三种类型的脚本元素:JSP脚本片段、JSP表达式和JSP声明,它们内部使用的都是java脚本代码。
      • JSP模板元素
        • JSP页面中的静态HTML内容称之为JSP模板元素。
        • 它定义了网页的基本骨架,即页面的结构和外观。
      • JSP表达式
        • 提供了一个将java变量或表达式的计算结果输出到客户端的简化方式,它将要输出的变量或表达式直接封装在<%=和%>之中。
        • JSP表达式中的变量或表达式后面不能有分号,它被翻译成Servlet程序中的一条out.print(...)语句。
      • JSP脚本片段
        • 嵌套在<%和%>之中的一条或多条java程序代码。
        • 在JSP脚本片段中可以直接使用JSP提供的隐式对象来完成web应用程序特有的功能,例如,使用out.println语句将数据输出到浏览器。
        • 多个脚本片段中的代码可以互相访问,犹如将所有的代码放在一对<%和%>之中。
        • 单个脚本片段中的java语句可以是不完整的,但是,多个脚本片段组合后的结果必须是完整的java语句。
        • 注:实际开发中:JSP中不能出现一行Java脚本片段和Java脚本表达式。
      • JSP声明
        • 在脚本片段中声明的变量将成为_jspService方法中的局部变量。
        • 如果希望在JSP页面中为其转换成的Servlet定义成员变量和方法,就需要使用JSP声明。
        • JSP声明将java代码封装在<%!和%>之中,它里面的代码将被插进Servlet的_jspService方法的外面。
        • JSP声明用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和成员方法,并且JSP声明中的java代码只能是静态代码块、成员变量和成员方法的定义。
        • 多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
        • 由于JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。
        • 对于JSP页面没有发生修改的情况下,对于JSP页面的每次访问请求,Servlet引擎都会调用其所生成的Servlet的_jspService方法进行响应。
      • EL表达式
        • EL表达式的基本语法格式为"${表达式}",它可以出现在JSP自定义标签和标准标签的属性值中,其计算结果将作为标签的属性值或属性值的一部分;EL表达式也可以出现在模板元素中,其计算结果将插入当前的输出流中。
        • 如果表达式的计算结果为null,JSP脚本表达式将输出内容为"null"的字符文本,而EL表达式会将它强制转换成空字符串("")后再输出,而不是显示为"null",这样的处理结果非常有用。
        • 在EL表达式中还可以使用empty操作符来判断一个参数是否为null,某个集合或字符串中的内容是否为空。
        • EL表达式还具有JavaScript等脚本语言的优点,能够对字符串、数字等各种类型的数据进行自动转换。
      • JSP注释
        • JSP注释的格式为<%--注释信息--%>。
        • JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。
        • JSP注释与JSP页面中的java注释和HTML注释的区别:
          • JSP引擎在翻译JSP页面时,将忽略JSP注释中的所有内容。
          • 在JSP引擎看来,出现在JSP脚本元素中的java注释属于java代码的一部分,它们将被原封不动地插入进Servlet源文件中,但在Servlet源文件被编译成class文件时,由java编译程序忽略。
          • 在JSP引擎看来,JSP页面中的HTML注释就是一段文本,其处理方式与普通的文本内容完全一样,都被转换成out.write语句输出到客户端。
          • 出现在JSP脚本元素之外的/*、*/和//不再属于java注释,而属于普通的文本字符,将被转换成out.write语句输出到客户端。
          • 由于HTML注释相当于一段普通文本,其中可以嵌入JSP的其他各种元素,JSP引擎依然会对这些嵌套的JSP元素进行解释处理。
      • 特殊字符序列的转义处理
    • JSP指令
      • JSP指令概述
        • JSP中定义了一种称之为JSP指令(directive)的元素,JSP指令是为JSP引擎而设计的,它们不直接产生任何输出,只是告诉引擎如何处理JSP页面中的其余部分。
        • JSP指令必须嵌套在<%@和%>之中,基本语法格式为:<%@ 指令 属性名="值" %>,其中属性名是大小写敏感的。
        • JSP中定义了page,include和taglib三种指令,每种指令中又都定义了一些各自的属性。
      • page指令
        • page指令用于定义JSP页面的各种属性。
        • 无论page指令出现在JSP页面的什么地方,它作用的都是整个JSP页面,最好将page指令放在整个JSP页面的起始位置。
        • JSP中的page指令的完整语法如下:
          <%@ page
          [language="java"]
          [extends="package.class"]
          [import="package.class" | package.*]
          [session="true | false"]
          [info="text"]
          [errorPage="relative_url"]
          [isErrorPage="true | false"]
          [contentType="mimeType [;charset=characterSet]"]
          [pageEncoding="characterSet"]
          [isELIgnored="true | false"]
          %>
        • language属性
          • 说明JSP页面所使用的脚本语言,默认为java。
        • extends属性
          • 指定JSP页面翻译成的Servlet所继承的父类,一般不要设置这个属性,让JSP引擎自行处理。
        • import属性
          • 指定在JSP页面翻译成的Servlet源文件中导入的包或类。
          • 在JSP页面翻译成的Servlet源文件中,Jsp引擎将把page指令的import属性翻译成相应的import语句。
          • JSP引擎自动导入下面的包:
            • java.lang.*
            • javax.servlet.*
            • javax.servlet.jsp.*
            • javax.servlet.http.*
        • session属性
          • 指定在JSP页面翻译成的Servlet中是否预先创建好session隐式对象,也就是指定在JSP脚本元素中是否可以使用session隐式对象。
          • 默认值为true。
        • buffer属性
          • 指定out隐式对象的缓冲区大小,默认值为8KB。
          • 如果将buffer属性设置为none,则out对象不使用缓冲区
        • autoFlush属性
          • 设置当out隐式对象的缓冲区已满时,是将其中的内容刷新到客户端,还是抛出缓冲区溢出的异常。
          • 默认值为true。
        • isThreadSafe属性
          • 设置JSP已满是否是线程安全的,是否需要让JSP已满翻译成的Servlet实现SingleThreadModel接口。
          • 默认值为true。
        • info属性
          • 用于将一个文本字符串定义为JSP页面翻译成的Servlet的描述信息。
          • web容器可以通过Servlet.getServletInfo方法获得该文本字符串。
        • errorPage属性
          • 用于设置另外一个JSP页面来处理当前JSP页面发生的异常。
          • 配置全局错误提示页面:(不是服务器转发技术)
            web.xml

            java.lang.Exception
            /error.jsp


            404
            /404.jsp

        • isErrorPage属性
          • 设置当前页面是否是专门用于处理其他页面的未捕获异常的JSP页面。
          • 默认值为false。
        • contentType属性
          • 设置响应正文的MIME类型和说明JSP文件中的文本内容的字符集编码。
          • 默认的MIME类型为text/html,默认字符集为ISO-8859-1
        • pageEncoding属性
          • 设置JSP引擎在翻译JSP成为Servlet时查询的码表。
        • isELIgnored属性
          • 指示是否忽略EL表达式。
          • 默认值false,不忽略。

你可能感兴趣的:(java学习笔记)