Web应用程序
Web程序是什么
Web应用程序就是一般所说的网站,由服务器,客户端浏览器以及网络组成。但Web程序又不是一般意义的网站,一般的网站是提供信息服务,重在内容,程序往往比较简单,但商用的Web程序往往比较复杂,背后结合数据库等技术。
B/S 与 C/S结构
根据是否需要网络,程序可以分为网络程序与非网络程序。其中网络程序可分为B/S结构与C/S结构。
B/S是指浏览器(Browser)/服务器(Server)模式。一般的网站都是B/S结构的。比如Google,Baidu。Web应用程序的访问不需要安装客户端程序,可以通过任意一款浏览器来访问Web应用程序。当Web应用程序进行升级时,不需要客户端进行任何改动。
C/S是指客户端(Client)/服务器(Server)模式。这个模式的客户端需要安装一个PCR程序。PCR程序负责与服务器进行数据交换。一般的网络程序都是C/S结构。比如QQ,微信,LOL等。缺点是服务器端进行升级时,客户端也要进行升级,这样会给客户端带来麻烦,也会占用资源。
Web访问基本原理
URL、URN与URI
Web应用的文件等资源是放在服务器上的,而服务器是Internet上的主机,那浏览器想从服务器取得资源,该这么办呢,或者说浏览器到服务器的哪里取得资源?那么就需要用到URL。
-
URL:Uniform Resource Locator 统一资源定位符。URL是可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址[Baidu]。主要格式为:
<协议>:<特定协议部分>
协议指定了以何种方式取得资源。一些协议的例子:
ftp(文本传输协议,File Transfer Protocol)
Http(超文本传输协议,Hypetext Transfer Protocol)
mailto(电子邮件)
file(特定主机文件名)
协议之后跟随:号,特定协议部分的格式为:
<用户>:<密码>@<主机>:<端口号>/<路径>
URN:Uniform Resource Name 统一资源名称。代表某个资源独一无二的名称。唯一标识一个实体的标识符,但是不能给出实体的位置。系统可以先在本地寻找一个实体,在它试着在Web上找到该实体之前。它也允许Web位置改变,然而这个实体却还是能够被找到[Baidu]。
URI: Uniform Resource Identifer 统一资源标识符。Web上地址的基本形式就是URI,它代表统一资源标识符,有两种形式,即URL与URN,URL与URN为URI的子集。
HTTP超文本传输协议
HTTP是什么?
HTTP协议是浏览器和服务器之间的应用层通信协议,简单来说就是浏览器和服务器之间对谈沟通的方式。它是基于TCP/IP之上的一种协议,TCP负责确保从一个网络节点向另一个网络节点发送的文件能作为一个完整的文件到达目的地,尽管在具体的传送过程中这个文件可能会被分解为小块传输。IP是一个底层协议,负责把数据块(数据包)沿路移动/路由到目的地。
HTTP的特性
HTTP有两个基本但极为重要的特性:
- 基于请求(Request)/响应(Response)模型:HTTP是一种基于请求/响应的通信协议,每次的联机只做一次请求/响应,是一种简单的通信协议,没有请求就没有响应。
- 无状态(Stateless)通信协议:在HTTP协议下,服务器端是一个健忘的家伙,服务器响应客户端之后,就不会记住客户端的信息,更不会维护与客户端有关的状态,因此HTTP协议也称无状态的通信协议。
HTTP请求
浏览器在使用HTTP发出请求时,可以有多种请求方法,比如GET、POST、HEAD、PUT、DELETE等。但对于编写Servlet或Jsp而言,最常接触的就是GET和POST两种请求方法。
请求的数据里面包含三个部分内容 : 请求行 、 请求头 、请求体。
GET
GET表示查询信息,URL中可以附带少量的参数信息,但是URL总长度不能超过255个字符,并且参数会显示在浏览器地址栏。
GET请求的请求参数是在URL之后跟随着一个问号(?),然后是请求参数名称(name)与请求参数值(value),中间以等号(=)表示成对关系,若有多个请求,则以&字符连接,GET请求可以发送的请求参数长度有限。
GET请求只有请求行和请求头。
一个简单的GET请求实例:
POST
POST表示提交信息,一般用于提交大数据信息或文件,提交的内容不受长度限制,并且不会显示在浏览器地址栏,而是把请求文本放置在了请求体(消息体)中。
POST请求包括请求行,请求头,请求体。
一个简单的POST请求实例:
如何选用GET或POST
-
从功能上讲:
- GET请求的请求参数长度是有限的,过长的请求参数或文件上传这类的大量数据,就不适合用GET请求,而应该改用POST请求。
- GET请求的请求参数会直接暴露在地址栏上,如果是敏感的或有安全性考虑的请求参数(如信用卡号码,用户名,密码等),就不应该用GET方法。
- POST请求的请求参数不会出现在地址栏里,所以无法加入浏览器的书签之中,有些页面是根据请求参数来作不同的画面呈现(如论坛的文章发表),以便可以直接点击书签浏览,则应该用GET请求。
- 有些浏览器依据网址缓存数据,如果网址是相同的URL,则会直接在浏览器缓存中取出数据,而不会真正发送请求查询最新的数据,如果不希望服务器状态改变了,则可以用POST请求。(GET请求也可以避免缓存,例如在网址上添加时间戳,让每次GET请求的网址都不一样)
-
非功能层面考虑:
也就是从请求是否为等幂操作来决定使用GET或POST,所谓等幂操作:就是请求的操作是否改变服务器状态,同一个操作重复多次,是否传回同样的结果。
- GET请求应该用于等幂操作。GET请求纯粹取得资源,而不改变服务器上的数据或状态。GET请求无论重复发送多少次,都应该传回同样的结果。
- POST请求应该用于非等幂操作。POST操作可能会影响服务器状态,例如修改(增删改查)数据库的内容,或是在服务器上保存文件。你的请求如果会改变服务器的状态,那么应该用POST请求。
- 就窗体发送而言,可以通过form的method属性来设置使用GET或POST方式来发送数据,通常如果不设置method属性,默认会使用GET。
静态页面动态页面
静态页面:指的是请求服务器上的网页时,服务器不对网页做任何处理,读取文件后直接当做响应传给浏览器。
动态页面:指的是服务器在响应之前,可能先依客户端的请求参数,标头或实际服务器上的状态,以程序的方式动态产生响应内容,再传回给用户。
Web容器(Tomcat)
Web容器的概念
容器这个名词也用在List,Set这类的Collection上,也就是持有,保存对象的集合对象。但对于编写Servlet/Jsp来说,容器的概念更广,它不仅持有对象,还负责对象的生命周期,与相关服务的连接。
在具体层面上,容器就是一个Java写的程序,运行在JVM之上.
在抽象层面上,可以将Web容器视为运行Servlet/JSP的HTTP服务器,只要Servlet/JSP符合Web容器的标准规范,Servlet/JSP就能在不同厂商的Web容器上运行,而不需要理会底层真正的HTTP服务器是什么。
Tomcat就是这样的容器,如果Web服务器应用(如Apache)得到一个指向某Servlet的请求,这个时候服务器不是把请求交给Servlet,而是交给该Servlet部署的容器。要由容器向Servlet提供HTTP的请求和响应,而且由容器调用Servlet的方法,如doGet(),doPost()。
从请求到Servlet处理的线性关系
容器能提供什么?
- 通信支持:通过Web容器Sevrlet可以与Web服务器轻松地对话,你不必担心Web服务器和你Web代码之间的API,你只管考虑如何实现在Servlet中的业务逻辑。
- 生命周期管理:容器控制着Servlet的生与死。它会加载类,实例化,和初始化Servlet、调用Servlet方法,并使Servlet实例能够被垃圾回收。你就不要太多地考虑资源管理了。美滋滋......
- 多线程支持:容器会自动地为它接收的每个Servle请求创建一个新的进程。针对客户的请求,如果Servlet已经运行完相应的HTTP请求服务,这个线程就会结束。值得注意的是Web容器可能会使用一个Servlet实例来服务多个请求,也就是说,在多个线程共享存取一个对象时,因此要注意线程安全问题,避免出现数据错乱。
- 声明方式实现安全:利用容器,可以使用XML部署描述文件来配置(和修改)安全性,而不必将其硬编码写到Servlet(或其他)类代码中。
- JSP支持:容器负责把JSP代码翻译成JAVA代码。
容器如何找到Servlet
作为客户请求的一部分,URL会以某种办法映射到服务器上的一个特定Servlet。一般使用部署文件将URL映射到Servlet,将Servlet部署到Web容器时,会创建一个相当简单的XML文档,这称为部署描述文件(DD),部署描述文件会告诉容器如何运行你的Servlet和JSP。使用两个XML元素就可以把URL映射到Servlet,其中一个将客户知道的公共URL名(搜索栏上的)映射到你自己的内部名(一个虚构的名字),另一个元素把你自己的内部名映射到一个完全限定类名(包括类名和包名)。
举例:
<servlet>
<servlet-name>xixi</servlet-name> 内部名,可以随便取,但要与下面一致
<servlet-class>servlet.LoginServlet</servlet-class> 完全限定类名,包括类名和包名
</servlet>
<servlet-mapping>
<servlet-name>xixi</servlet-name> 内部名,可以随便取,但要与上面一致
<url-pattern>/Login</url-pattern> 公共URL名,完全给用户提供的,给用户进行访问的,公共URL名前不能少了/号!!!
</servlet-mapping>
建立Servlet名的映射,这有助于改善应用的灵活性和安全性。