[Java Web]Web应用基本概念

本文详细介绍了Web应用程序的构成、URL、URN、URI编码问题、HTTP协议、浏览器的HTTP请求方法、GET和POST的区别及选用依据、动态网页与静态网页的本质、Web容器、Servlet与JSP的关系、MVC设计模式、JavaEE开发平台及其规范,以及Web开发中的关键概念和技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Web应用程序的构成:

    1) 主要由两部分构成:客户端和服务器端,其中客户端基本是浏览器,服务器端是HTTP服务器;

!HTTP即HyperText Transfer Protocol的简称,即超文本传输协议;

!!注意,两端都是应用程序,浏览器是应用程序,HTTP服务器也是一种安装在操作系统上的应用程序,在该服务器程序中为具体的Web程序(如Servlet等)提供Web容器;

    2) 两端交流的方式:浏览器请求服务器上放置的资源,而服务器则要响应请求并返回相应的资源,而对于Servlet/JSP来说必须返回HTML文件供浏览器呈现;


2. URL、URN、URI:

    1) UR为Uniform Resource的意思,而L、N、I分别是Locator、Name、Indentifier的缩写,即统一资源定位器、名称、标识;

    2) 历史上三者是按照URL、URN、URI的顺序出现的,URL和URN是标识互联网资源的两种不同方式,而URI后来将这两种规范统一起来了,因此URL和URN是URI的子集;

    3) URL格式:[scheme://][<user>:<passwd>@]<hostname>:<port>/<path>

!其中scheme是使用的网络传输协议,例如HTTP协议就填写HTTP,而“<用户名>:<密码>@”可以不写表示以游客身份登录,主机名<hostname>可以使用文字或数字形式(建议使用文字,以为URL的初衷就是用文字来表示互联网各个计算机上的资源),比如www.baidu.com就是一种主机名,当然也可以写192.xxx.xxx的数字的版本;

!路径就是指资源在服务器程序中的虚拟目录中的路径;

    4) URI除了有URL之外还可以包含请求参数,即在URL后面还可以跟随一些额外的信息(参数),只有服务器上必须有针对这些额外请求参数的服务则这些额外的请求才会起到作用(处理额外请求需要在服务器端刻意编程实现):

         i. 必须在URL最后加一个?表示请求参数的开始;

         ii. 请求参数的格式是:arg_name1=value1[&arg_name2=value2][&arg_name3...

         iii. 可以看到参数是以键值对的形式出现的,即“参数名=参数值”的形式,如果有多个参数则使用&进行连接;

         iv. 例如?user_id=1011,这样的话服务器端程序必须有检测user_id参数名称的逻辑存在;

    5) 常用的协议:

         i. http:超文本传输协议,例如http://www.baidu.com

         ii. ftp:File Transfer Protocol,文件传输协议

         iii. mailto:电子邮件协议,例如mailto://xxxx_xxx@163.com

         iv. file:特定主机上的文件路径,例如打开本机文件则可以直接在浏览器中输入file://c:/workspace/test.txt

!!可以看到在URL中,file的路径分隔符是一定的,即/,如果你是在Windows的资源管理器中输入文件路径,则分隔符必须是\,URL将路径格式都统一了起来;

    6) URN:表示某个资源独一无二的名称,比如一本书可以用它的国际标准书号ISBN XXX-X-XXX-XXXXX-X来表示,URN不仅可以标识网络资源也可以表示实体,作用范围更大,但是在网络世界中,网络资源的表示还是URL更加方便和普遍;


3. URL编码问题:

    1) URI规定和HTTP规定:URI统一了所有协议的URL编码,但是由于部分协议出现的要比URI规范早很多,早就已经有自己的编码规范了,因此这些协议虽然大部分都遵守URI编码规范,但是也有一部分遵循自己传统、特有的规范,比如URI中空格的编码是%20,而HTTP中空格的编码则是+,由于+对空格的编码由来已久所以HTTP仍然沿用该编码;

!!!在搜索引擎中经常将空格当成关键词的连接符号,将空格编码成+也方便对字符串的解析;

    2) URI保留字:保留字即能起到特殊作用的字符,就好像C语言中的关键字,例如:、/、?、&、=、@、%等,如果想让这些特殊字符作为纯文本字符出现在URL中,则必须要转义,在URI中转义符号是%,要在%后紧跟需要转义的字符的编码,例如:的ISO编码(16进制)是3A,则必须用%3A来代表:的纯文本;

    3) HTTP对GET和POST的保留字做了一定的特殊规范,其中之一就是空格的编码是+;

    4) Java对URI编码和解码的支持,如果你想将一个字符串转化成URI编码形式则可以使用String java.net.URLEncoder.encode(String s, String enc);函数,比如:

String text = java.net.URLEncoder("http://hello.c", "ISO-8859-1"); // 按照ISO的编码规则将前面一个字符串转化成http%3A%2F%2Fhello.c,其中:和/都需要转义

!在上面的例子中你可以将这一整条URL当做另一个URL中的请求参数

!!而解码则使用String java.net.URLDecoder.decode(String s, String enc);

    5) 关于中文字符:

         i. 在URI规范下中文字符使用UTF-8来编码,在UTF-8中一个字符用一个字节来编码,而中文字符体系庞大不可能只用一个字节就能将所有中文编码完,因此URI规定用三个字节对一个中文进行编码,比如”林“就用%E6%9E%97三个字节编码;

         ii. 在HTTP规范下不仅可以使用UTF-8编码,还可以用其它多种编码方案,比如BIG5,在该编码规范下”林“用两个字节编码%AA%4C;

         iii. 中文编码解码同样可以使用java.net的Encoder和Decoder,只不过enc要指定清楚是那种编码方案;

    6) 浏览器地址栏智能转换:有时可以发现浏览器地址栏可以显示中文字符,但其实不然,如果你将地址栏中的URL复制黏贴到无格式的文本编辑器中就会发现那些中文字符的地方被替换成了各种%XX之类的编码,这其实是浏览器的智能功能,某些浏览器可以根据当前网页的编码将地址栏中的编码符号在视觉层面上转化成实际的字符显示给用户,使之一目了然;


4. HTTP简介:

    1) 是一种建立在TCP/IP这种底层协议之上的应用层协议,是一种较高层的协议;

!!当然还有其它很多应用层通信协议,比如SMTP(Simple Mail Transfer Protocol)用于发送信件,POP3(Post Office Protocol 3)用于下载信件等;

    2) HTTP是一种基于请求/响应的无状态通信协议:

         i. 客户端必须向服务器端发送请求服务器端才能响应,没有请求就没有响应,并且每次联机只能作出一次请求/响应;

         ii. 在HTTP写一下,服务器端非常健忘,不会记录客户端的信息更不会去维护客户端的状态,因此是一种无状态协议;


5. 浏览器的HTTP请求方法:

    1) 客户端的浏览器可以使用GET、POST、HEAD、PUT、DELETE等方式向服务器端发送请求;

    2) 其中最常用的(特别是对于Servlet、JSP编程而言)就是GET和POST两种方式(在大多数情况下只会用到这两种方式),因此这里我们先只介绍GET和POST请求方式;

    3) 首先需要了解一下请求报文的格式:

         i. 请求报文就是不管用什么方式(GET还是POST还是HEAD等),请求的信息都会封装在请求报文中,它具有一定的格式;

         ii. 报文格式决定了请求的方式;

         iii. 格式框架(从左到右按照顺序排列):HTTP请求方法 + URL + [请求参数] + HTTP版本 + 请求标头 + [请求参数]

!!如果请求参数放在HTTP版本之前则是GET请求方式,如果请求参数放在最后则是POST请求方式,例如:

GET hostname/path?file=servlet&user_id=10111 HTTP/1.1
User-Agent:Mozilla/5.0...
...
Accept-Language:en, zh
!!其中请求方法、URL、请求参数、HTTP版本号都好理解,其中HTTP版本号的书写格式是"HTTP/版本号数字编码"

    4) HTTP请求标头:标头的内容是为了给服务器端作额外的参考用,服务器端可以选择性地使用这些信息做适当的响应,比如很多浏览器之间不兼容,而服务器端的程序为各个不同的浏览器准备了不同版本的响应,此时就可以读取标头中的User-Agent域,根据里面透露的用户使用的浏览器品牌和版本给予特定的响应,而Accept-Language则透露了浏览器可接受的语言种类;

!!标头的格式是每行一个参数解释“参数名:解释字符串”;

    5) GET和POST的不同:

         i. 浏览器的地址栏上不会显示标头以及标头以后的内容,如果使用GET方法则请求参数会显示在浏览器的地址栏中,如果请求参数有一些敏感信息,如密码等则会造成信息的不安全,因此使用POST可以隐藏敏感信息;

         ii. 使用GET时请求参数的长度是有限的(不同浏览器限制的长度不尽相同),如果要发送大量参数则使用GET时显然不合适的,此时只能使用POST;

!!典型的案例就是网络爬虫,比如在一个蛋白质数据库中想爬去跟p1、p2、p3...p9999有关的蛋白质,因此需要在参数protein_id中填写完所有要找的蛋白质名称“protein_name=p1,p2...p9999”,此时使用GET方法请求参数必然超出限制长度,因此只能使用POST方法了;

         iii. 请求报文中请求标头后面的部分叫做信息体(Message Body),对于POST请求方式来说请求参数就位于信息体中了,对于HTTP报文,信息体的长度是不受限制的,因此使用POST可以无限填写请求参数;


6. 选用GET和POST的依据:除了之前说过的两种情况之外很多请求既可以使用GET也可以使用POST,那么该如何选用这两种请求呢?

    1) 从需求方面看:

         i. 如果请求内容非常庞大(如上传文件,是的,你可以将要上传的整个文件填写在信息体中,也可以整个填写在请求参数中,例如file_content=...)则使用POST;

         ii. 如果请求参数中存在敏感信息(如密码等)则使用POST;

         iii. 如果想将根据请求参数返回不同画面的网页保存在浏览器书签中(Bookmark)则必须使用GET,因为浏览器只能根据地址栏中的内容保存书签,例如你要保存sina.blog?user_name=xxx&page=5的网页作为书签,则请求参数必须出现在地址栏中,如果使用POST则请求参数保存在了信息体中,如果这个时候点击添加书签则保存的是sina.blog这个主页了,因为地址栏上出现什么浏览器就保存什么,请求参数没有出现在地址栏中,那么根据请求参数返回的页面就无法被保存为书签;

         iv. 避免浏览器缓存使用POST,使用GET请求的网页内容会自动保存在浏览器的缓存中,如果下次再用GET打开相同URI的网页则浏览器不会再向服务器发送器请求,而是直接从缓存中打开网页内容,这样可以加快网页的打开,优化用户体验,但是如果你不希望网页更新了但还从换从中打开旧的资料就得使用POST方式,POST方式不会缓存网页;

!!其实GET方式也可以避免缓存,只要在网址上附上时间戳就行了;

    2) GET和POST的设计初衷:区别是否为等幂操作

         i. 等幂操作的意思就是重复操作得到相同的结果,幂在数学中就是重复的意思,这里就是指重复相同的请求是否能得到相同的结果;

         ii. 当然上面只是表面上的意思,更深层次是指请求是否会改变服务器的状态,如果不改变则是等幂操作,否则就是非等幂操作;

         iii. 等幂操作要求请求不能改变服务器上的数据和状态,如查询数据库、单纯地返回一个页面等,这种操作重复多次也只会返回相同的结果,而非等幂操作会改变服务器的数据和状态,比如修改数据库(增删改等),或是在服务器上上传文件;

         iv. GET用于等幂操作,POST用于非等幂操作;

!例如在HTML的表单操作中,可以使用method属性决定使用GET还是POST,比如<form method="get";


7. 动态网页与静态网页的本质区别:

    1) 静态网页一般使之HTML和JavaScript编写的网页,当浏览器请求后服务器原封不动的返回给用户的网页,你不该代码则网页中的内容永远也不会自动改变;

    2) 动态网页一般是由服务器按照一定的逻辑生成的,服务器会根据客户端的请求内容,通过一些工具(如Servlet、JSP等)动态生成用户需要的HTML、JavaScript页面返回给用户,例如搜索引擎就能根据用户输入的搜索内容不同返回给用户不同的页面;

    3) 动态技术和静态技术的本质差别:静态网页只能运行在客户端的浏览器中,如HTML、JavaScript,而动态网页(精确地讲,像PHP、JSP、Servlet等)只能运行在服务器端,它们可以根据用户的请求按照一定逻辑生成HTML、JavaScript代码返回给浏览器去执行,两者运行在不同的内存空间,前者运行在用户机器的内存空间,后者运行在服务器机器上的内存空间;

    4) 处理动态网页的技术:CGI(Common Gateway Interface)、PHP(Hypertext Preprocessor)、ASP(Active Server Pages)、Servlet/JSP(Java Server Pages)等;

    5) 记住!虽然可以在JSP中可以编写一些HTML、JavaScript代码,但是这些代码永远都不会在服务器端运行,它们会原封不动地传给浏览器运行,所以概念千万别搞混了;


8. Web容器:

    1) 首先要理解容器的概念,容器在Java中就是一种集合,可以持有各种对象,例如List、Set等就是容器(可以装盛多个对象),因此Web容器用来装盛各种和Web操作有关的对象;

    2) 先来看一下Web容器在”请求到Servlet处理返回“流程中的位置:浏览器——实体服务器——HTTP服务器程序——Web容器——Servlet

         i. 其中HTTP服务器程序就是一些底层的网络驱动程序,用C语言实现,就像操作系统一样都是系统程序(就跟Unix上C语言实现的TCP/IP协议一样);

         ii. Web容器就是对这些面向过程的协议程序进行Java的面向对象包装,然后就可以在Servlet中调用这些对象使得Web编程更加方便容易;

!!这又没感觉跟MFC体系很想呢?机器——Windows操作系统底层API(都是面向过程的C语言)——包装成MFC面向对象框架——使用MFC类库编写的应用程序;

!!其实Servlet、JSP等都是服务器上的应用程序,只不过他们使用的是Web容器这种框架编写的;

    3) Servlet/JSP运行的Web容器其实就是一个用Java编写的程序,其本质就是将体层的C语言写的HTTP协议程序包装成Java的面向对象的程序框架,里面持有诸如HttpServletRequest、HttpServletReponse等和Web操作有关的对象;

!Web容器不仅仅是一个类库(编程),也是一个运行时环境,你要进行Web通信那么Web容器必须开启,你要使用Web容器的特定功能就必须调用它提供的函数,这是不是跟操作系统有点像呢?操作系统不仅是一个编程库(提供各种各样的系统调用),也是一个运行时环境,如果你不打开操作系统那应用程序该如何运行呢?

!其实就可以把Web容器看成Web程序的操作系统;

    4) 在Java Web中真正负责请求响应的只有Servlet,JSP其实也是Servlet,Web容器会将JSP编译成Servlet程序并加载运行;

    5) 一个请求响应的完整流程:

         i. 客户端发出请求;

         ii. HTTP服务器接受请求并交由Web容器;

         iii. Web容器剖析HTTP请求(并将相关信息保存在创建的HttpServerRequest、HttpSession等对象中);

         iv. Web容器根据请求信息决定使用哪个Servlet处理(如何决定由编程实现),并加载那个Servlet进行处理(同时将相关的Web对象,HttpServerRequest对象等,传给响应的Servlet);

         vi. Servlet根据Request对象将响应保存在Response中回应;

         v. 响应再原路返回传给客户端;

    6) Web容器的多线程处理:

         i. 有时会在短时间内接收到多个请求,此时Web容器就会为每个请求开辟一个线程,每个线程中分配一个Servlet来响应;

         ii. Web容器运行同一个Servlet实例为多个请求服务,因此这些多线程之间共享相同内存空间,这个时候就要注意线程安全问题了;


9. Servlet和JSP的关系:

    1) JSP虽然是网页文件,但是该网页文件不能由浏览器执行,以为它是服务器程序,只能由服务器端的Web容器执行;

    2) JSP会被Web容器编译(会先转义成.java文件)成Servlet的.class可执行文件(对于JVM来说是可执行文件),再被JVM执行(执行时和Web容器相互配合工作);

!!因此也可以直接在JSP中调用Java的语句;

    3) 在JSP中出现的HTML、JavaScript静态网页语句会被原封不动地传给浏览器执行,这些语句在编译成Servlet后可以看到其实是用out.wirte一条条打印出来的;


10. MVC/Model 2设计模式:

    1) 刚刚讲过了,可以在Servlet中进行HTML、JavaScript的画面输出(.jsp到.java的转义结果可以看到,.jsp中的<html>等语句会被转化成Java的out.write("<html>")输出语句,其实就是用Servlet来生成HTML代码,因此可以在Servlet中进行画面输出),也可以在JSP中编写Java代码,但是这样做是一种很混乱的行为,编写不易、维护不易也不利于团队分工合作;

    2) 因此提出了MVC/Model 2框架使Web应用程序开发更加规范和高效:

         i. MVC即Model、View、Controller三者的缩写,这三个模块分别负责Web应用的模型、视图和控制器;

         ii. MVC最早是一种桌面应用程序的设计模式,但是要沿用到Web程序的设计上,但是Web应用程序和桌面应用程序有很大的不同(Web程序基于HTTP请求响应的),因此再后来发展出了一套适用于Web的MVC模式,为了和桌面程序的MVC相区别,因此就命名为MVC/Model X,其中Model 1是Java Bean的Web规范,而Model 2是SSH框架规范(Struts、Spring、Hibernate框架规范);

    3) MVC模型下的Web分工:

         i. 视图负责画面的输出,由网页来实现;

         ii. 模型负责具体的业务逻辑和数据访问(后台程序);

         iii. 控制器负责浏览器的请求,并决定由哪个模型来处理该请求;

    4) 在MVC规范下就不允许出现在JSP使用Java代码、在Servlet中画面输出的不规范行为,各个模块各司其职,相互之间尽量不要耦合;


11. Java EE简介:

    1) Java不仅仅代表一种编程语言,也代表了一个开发平台,按照开发平台不同分为Java SE、ME、EE三种版本,分别代表了Java Platform Standard、Micro、Enterprise Edition三种版本;

    2) SE面向桌面应用,ME面向微型终端上的应用(移动终端如手机等,嵌入式终端如微波炉、面包机、机器控制器等),而EE则面向企业,为企业提供所有可能遇到的各个领域的问题的解决方案,它基于SE,但囊括了SE、ME以及其它更多的工具;

    3) Java EE体系庞大,其中Servlet/JSP就是Java EE中Web容器的一个技术规范;

    4) 分清Java开发平台和JDK的关系,有人会以为不同开发平台会有不同的JDK,其实不然,所有平台用的都是同一种JDK,开发平台不仅需要JRE和JDK,也需要支持该平台的其它软件,比如Java EE除了需要JRE、JDK,还需要Web容器、Web框架等组件,Java ME还需要嵌入式平台等组件,JDK和JRE只是开发平台中的一部分,并不仅仅只有它们俩:

!!还有就是Java开发平台规定的只是一种技术规范,比如规定了JRE的技术规范、规定了Web容器的技术规范,同一个技术规范下不同厂商的实现产品,比如JDK、JRE最流行的是Oracle提供的实现,Web容器可以使用Apache Tomcat提供的实现,如果你足够厉害你可以自己实现符合Java平台规范的JVM虚拟机、Web容器等;

    5) Java开发平台规范的制定和发布:

         i. 规范制定的委员会JCP:Java Community Process,该组织开发、审核、投票、发布规范,该组织将决定平台应用的组件、特性、编程接口等;

         ii. 发布规范文件JSR:Java Specification Requests,定制出来的规范会议JSR文件的形式发布,每个JSR文件会给予一个编号,如果你想查询某个JSR则可以登录JCP官网http://jcp.org,并在搜索页面中输入相应JSR的编号并下载文档阅览;

         iii. 不同企业厂商更具JSR的具体规范实现各自的开发平台,因此各个厂商提供的开发平台可能会有所不同,但会体现出各个品牌的特色;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值