您的位置:首页 > 职场人生

Java学习笔记-《Java程序员面试宝典》-第5章Java Web-5.1Servlet与JSP(5.1.1-5.1.7)

2017-06-27 21:18 761 查看

5.1.1 页面请求的工作流程是怎样的

一个Web应用程序一般都是由客户端程序与服务器端程序两部分组成。其中,客户端主要是指用户和浏览器,用户可以通过浏览器查找所需的资源,而这些资源位于服务器上。浏览器是一个工具软件,它主要有两个作用:一是完成与服务器端的交互;二是完成HTML(Hyper-Text Markup Language,超文本标记语言,用来告诉浏览器怎样给用户展示内容)的解析,从而实现把用户需要查看的资源信息以直观的形式展现出来。服务器端用来接收客户端发来的请求,并对该请求进行处理,找到客户端请求的资源,最后把查找到的资源返回给客户端,这些资源主要包括HTML页面、图片、音频、视频、PDF文件等内容。

下图给出了最基本的页面访问的处理流程:



1>用户通过浏览器输入链接地址来请求所需的资源。

2>浏览器接受用户的请求,并把该请求组装成指定的格式发送给服务器端,客户端与服务器端之间通过HTTP来完成具体的交互。其中请求的数据流中主要包含HTTP请求方法(GET或POST)、请求的网址(URL,Uniform Resource Locator,统一资源定位符)以及请求的一些参数信息。

3>服务器接收到客户端发来的请求,并查找用户所需的资源。

4>服务器查找到用户请求的资源后,把该资源返回给客户端。

5>服务器通过把响应消息组装成特定的消息格式后返回客户端,这个过程通过HTTP来完成。响应的数据流主要包含状态编码(代表请求成功或失败),Content-type(例如text,picture,HTML等),响应消息的内容(图片或HTML格式的内容)。

6>浏览器对HTML进行解析,并把响应结果展现给用户。

5.1.2 HTTP中GET与POST方法有什么区别

HTTP请求的方法有很多类,例如GET、POST、HEAD、TRACE、OPTIONS等,但是GET与POST是两个最常用的方法。其中,GET是最简单的一种请求方法,其主要功能是从服务器端获取用户所需的资源,并将其作为响应返回给客户端,这些资源可以是HTML页面、图片、文档等内容中的任何一种,但需要注意的是,GET方法的作用主要是用来获取服务器端资源信息,就如同数据库中查询操作一样,不会影响到资源自身的状态,例如删除、修改或新增资源都是不允许的。而POST方法提供了比GET方法更强大的功能,它除了能够从服务器端获取资源外,同时还可以向服务器上传数据。

虽然GET方法主要用来从服务器上获取数据,也可以向服务器上传数据,但是一般不建议采用GET方法来向服务器上传数据,而是推荐使用POST方法实现该功能。具体而言,主要有以下两个方面原因:

1>采用GET方法向服务器上传数据时,一般将数据添加到URL后面,并且二者用”?”连接,各个变量之间用”&”连接。由于对URL的长度存在限制,因此采用这种方法能上传的数据量非常小,通常在1024Byte左右。而POST方法传递数据是通过HTTP请求的附件进行的,传送的数据量更大一些,一般默认为不受限制的。

2>由于GET方法上传的数据是添加在URL中的,因此上传的数据被彻底”暴露”出来了,本身存在安全隐患,尤其是当用户需要向服务器提交一些敏感信息时。而POST方法向服务器提交的内容在URL中并没有明文显示,对用户都是不可见的,所以,安全性更好一些。

5.1.3 什么是Servlet

HTML只能用来保存静态内容,而通常情况下,静态页面很难满足实际应用的需要,鉴于此,动态页面的概念被引入。所谓动态页面,指的是能够根据不同时间、不同用户而显示不同内容的页面,例如常见的论坛、留言板、电子商务网站等都是通过动态页面来实现的。那么如和才能生成动态页面呢?其中一种方法是采用公共网关接口(Common Gateway Interface,CGI)。CGI是一种用Perl脚本写的程序,可以用来生成动态页面,而另一种方式则是采用Servlet技术。

什么是Servlet呢?Servlet是采用Java语言编写的服务器端程序,它可以运行于Web服务器中的Servlet容器中,其主要功能是提供请求/响应的Web服务模式,可以生成动态的Web内容,而这正是HTML所不具备的功能。

与其他生成动态网页的技术相比,Servlet有诸多优点,具体而言,主要表现在如下几个方面:

1)较好的可移植性。由于Java语言具有跨平台和可移植性强的特点,使得Servlet也有较好的可移植性,即无需修改代码就可以部署到多种不同类型的Web服务器上。

2)执行效率高。由于CGI针对每个请求都会创建一个进程来处理,而Servlet针对每个请求创建一个线程来执行,而创建线程比创建进程的开销要小,因此与CGI相比,Servlet在交互过程中有更短的响应时间,响应效率更高。

3)功能强大。Servlet可以与Web服务器进行交互,而CGI却无法与Web服务器直接交互。

4)使用方便。Servlet提供了许多非常有用的接口以用来读取或设置HTTP头消息,处理Cookie和跟踪会话状态等。

5)可扩展性强。由于Servlet是用Java编写的,因此它具备了Java语言的所有优点。Java语言是健壮的、面向对象的编程语言,它很容易扩展,Servlet自然也具备这样的优点。

为了更好的说明Servlet,在介绍Servlet处理请求的过程前,首先引入Servlet程序的基础结构,如下所示:

public class MyServlet extends HttpServlet{

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{

}

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{

PrintWriter out = response.getWriter();
out.println("some html formate string");
}

}


从以上的Servlet的程序结构中可以看出,在Servlet中并没有main()方法,连所谓的入口方法都没有,那么它到底是如何执行的呢?其实,它是在容器的控制下执行的,最常被使用的容器为Tomcat。当Web服务器获取到一个对Servlet的请求时,该服务器将会把这个请求交给对应的容器来处理,容器通过调用Servlet的方法(doGet()或doPost())来响应客户端的请求。

具体而言,Servlet处理客户端请求有如下几个步骤:

1)用户通过单击一个链接来向Servlet发起
4000
请求。

2)Web服务器接收到该请求后,会把该请求交给相应的容器来处理,当容器发现这是对Servlet发起的请求后,容器此时会创建两个对象:HttpServletResponse和HttpServletRequest。

3)容器可以根据请求消息中的URL消息找到相应当的Servlet,然后针对该请求创建一个单独的线程,同时把第2)步中创建的两个对象以参数的形式传递到新创建的线程中。

4)容器调用Servlet的service()方法来完成对用户请求的响应,service()方法会调用doPost()或doGet()方法来完成具体的响应任务,同时把生成的动态页面返回给容器。

5)容器把响应消息组装成HTTP格式返回给客户端。此时,这个线程运行结束,同时删除第2)步创建的两个对象。

以上流程如下图所示:



容器会针对每次请求创建一个新的线程进行处理,同时会针对每次请求创建HTTPServletResponse和HttpServletRequest两个对象。处理完后线程也就退出了。

5.1.4 doPost()方法与doGet()方法怎么选择

从Web容器处理HTTP请求的流程中可以看出,最终的请求都会交给Servlet来处理,而Servlet是通过调用service()方法来处理请求的,service()方法会根据不同的请求类型分别调用doPost()方法(处理Post请求)或doGet()方法(处理Get请求)来处理用户请求,实现对客户的响应。如果请求是GET,就调用doGet()方法;如果请求是POST,就调用doPost()方法。在Servlet接口和GenericServlet(一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口)中是没有doGet()方法与doPost()方法的,而HttpServlet中定义了这些方法,但是都是返回error信息,所以,当定义一个Servlet时,都必须实现doGet()方法或doPost()方法。doGet()和doPost()都接受请求(HttpServiceRequest)和响应(HttpServletResponse)。

具体而言,当HTTP请求中的method属性为get时,调用doGet()方法;当method属性为post时,则调用doPost()方法。

5.1.5 什么是Servlet的生命周期

由于Servlet运行在容器中,没有main()方法,因此,整个生命周期都是由容器来控制的。简单而言,Servlet的声明周期还有两个状态:为创建状态与初始化状态。这两种状态的转换主要是由3个重要额方法来进行控制:init()、service()和destory()。其中,init()方法是Servlet生命的起点,用于创建或打开任何与Servlet相关的资源以及执行初始化工作。service()方法是Servlet中真正处理客户端传过来的请求的方法,它根据HTTP请求方法(GET、POST等)将请求发送到doGet()、doPost()等方法。destory()方法释放任何在init()方法中打开的与Servlet相关的数据。

Servlet的状态图如下所示:



具体而言,Servlet的生命周期可以分为加载、创建、初始化、处理客户请求和卸载5个阶段。

1>加载。容器通过类加载器使用Servlet类对应的文件来加载Servlet。

2>创建。通过调用Servlet的构造函数来创建一个Servlet实例。

3>初始化。通过调用Servlet的init()方法来完成初始化工作,这个方法是在Servlet已被创建但向客户端提供服务之前调用的,需要注意的是,init()只会被调用一次。

4>处理客户请求。Servlet一旦被创建后,它就可以为客户端提供服务了。每当有新的客户请求到来时,容器都会创建一个新的线程来处理该请求,接着会调用Servlet的service()方法来完成客户端的请求,当然,service()方法会根据请求的method属性值的不同调用决定是调用doGet()方法还是调用doPost()方法来完成具体的响应。

5>卸载。容器在卸载Servlet之前需要调用destory()方法,让Servlet自己释放其占用的系统资源,一旦destory方法被调用,容器就不会再向这个Servlet发送任何请求消息了。如果容器需要这个Servlet,那么就必须重新创建并初始化一个实例。需要注意的是,destory()方法只会被调用一次。

5.1.6 JSP有哪些优点

JSP(Java Server Pages)是由Sun公司倡导、许多企业参与建立起来的一种动态技术标准,从本质上来将,就是嵌入了Java代码的HTML文件(但需要注意的是,JSP页面最好少写Java代码)。在引入JSP之前,在Web应用程序中,所有业务逻辑和HTML的响应都是在Servlet中实现的,但在使用这种方式时,存在一个比较大的缺陷:必须把用户响应的视图组装成一个很长的HTML格式的字符串写入println()方法中。所以,使用这种方式编程,在编写一段很长的HTML字符串时非常容易出错,而且代码的可读性也非常差,同时由于业务逻辑与视图没有分离,系统的可扩展性、可维护性都较差。

JSP的引入在一定程度上解决了Servlet存在的缺点。其实现理念是让每个Servlet只负责其对应的业务逻辑的处理,让JSP来负责用户的HTML显示,因此实现了业务逻辑与视图实现的分离,从而极大地提高了系统的可扩展性。

在引入JSP后,Servlet的实现结构如下:

public class MyServlet extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletExecption,IOException{
//business logic code
//forword the request to a JSP page
}
}


5.1.7 JSP与Servlet有何异同

JSP与Servlet的相同点为:JSP可以被看作一个特殊的Servlet,它只不过是对Servlet的扩展,只要是JSP可以完成的工作,使用Servlet都可以完成,例如生成动态页面。由于JSP页面最终要被转换成Servlet来运行,因此处理请求实际是编译后的Servlet。

JSP与Servlet的不同点为:1)Servlet的实现方式是在Java中嵌入HTML代码,编写和修改HTML非常不方便,所以它比较适合做流程控制、业务处理;而JSP的实现方式为在HTML中嵌入Java代码,比较合适页面的显示,例如,在Struts框架中,Servlet位于MVC设计模式的控制层,而JSP位于视图层。2)Servlet中没有内置对象,JSP中的内置对象都是必须通过HttpServletRequest对象、HttpServletResponse对象以及HttpServlet对象得到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息