一、什么是servlet
我们使用电脑在天猫商城买东西的时候,商品往往都有相应的图片,当我们点击不同的商品就会显示不同的图片。这个过程其实是请求服务器资源的过程。在很久以前还是使用的servlet技术的时候,服务器的处理机制就是通过servlet来完成的。现在我们给servlet一个标准的定义:
servlet是运行在web服务器中的小型java程序,通常通过HTTP协议接受和相应来自web客户端的请求。
它的特点如下:
(1)Servlet对像,由Servlet容器创建。通常这个容器就是tomcat。
(2)Servlet是一个接口:位于javax.servlet包中。
我们直接通过案例来分析会更加的清晰。
二、servlet案例
毕竟不是专门介绍servlet的使用的,我们直接通过案例来分析。在这里我使用的的IDE是Myeclipse,首先新建了一个ServletTest项目,根路径就是项目名字,然后在com.fdd.servlet包下,建了一个MyServlet1类,内容如下:
public class MyServlet1 implements Servlet{ public ServletConfig getServletConfig() { System.out.println("getServletConfig"); return null; } public String getServletInfo() { System.out.println("getServletInfo"); return null; } public void init(ServletConfig arg0) throws ServletException { System.out.println("init"); } public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("service"); } public void destroy() { System.out.println("destroy"); } }
现在我们已经创建了一个Servlet,但是如何去使用呢?我们还需要去注册一下这个Servlet。注册好了,客户端才能访问。注册的时候就是在web.xml里面注册,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 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"> <!-- 创建一个servlet实例 --> <servlet> <servlet-name>servletDemo</servlet-name> <servlet-class>com.fdd.servlet.MyServlet1</servlet-class> </servlet> <!-- 给刚刚的servlet实例, 提供一个外界可以访问的地址--> <servlet-mapping> <servlet-name>servletDemo</servlet-name> <url-pattern>/demo1</url-pattern> </servlet-mapping> </web-app>
注册的时候分为了两步:
(1)把MyServlet1作为一个实例注入进来
(2)给这个实例提供一个外界可以访问的地址,目前的地址是/demo1。
此时我们访问http://localhost:8080/ServletTest/demo1就相当于访问了我们的Servlet。这个案例很简单。下面我们分析一下这个整体的访问过程是什么样的。
三、请求过程
上面通过案例演示了整体的效果,但是整个流程是怎么样的呢?我们给出一张图就明白了
上面这张图基本上把整个流程算是交代清楚了。现在我们梳理一遍。
(0)Tomcat容器中通过web.xml加载所有的Servlet。
(1)用户在浏览器输入不同的地址,向Tomcat容器请求资源。
(2)Tomcat容器根据地址首先在容器内找到应用ServletTest。
(3)Tomcat容器再根据地址去web.xml找到相应的servlet地址(/demo1)。
(4)Tomcat容器根据找到的servlet地址(/demo1)去web.xml找到相应的Servlet类,并实例化。
(5)Tomcat容器实例化相应的Servlet,首先调用init方法。
(6)Tomcat容器实例化相应的Servlet,首先调用service方法处理用户请求,比如post或者是get。
(7)Servlet处理完成之后,现将数据给Tomcat容器,Tomcat容器再把处理结果给浏览器客户端。
(8)Tomcat容器调用servlet实例的destory方法销毁这个实例。
步骤比较容易理解。可以对比着上面的过程图来记忆。下面我们看看其生命周期。
四、生命周期(重点)
如果你理解了上面的执行过程,对于其生命周期想必也有了一个大概的了解,比如说init方法、service方法、destory方法。其实也就是这三个方法:
(1)init:第一次请求资源的时候,执行且只执行一次init方法。
(2)service:第二次往后,执行service方法,执行多次。在这个方法内部,根据请求方式的不同,进而继续调用不同的doGet和doPost方法。
(3)destory:当Servlet服务器正常关闭时,执行destroy方法,只执行一次。
五、常见面试题
在一开始举的例子中我们直接继承的是Servlet接口,这个类比较原始。需要我们自己处理各种事件。其实java已经我们提供了很多封装好的Servlet类,比如GenericServlet。
1、GenericServlet和HttpServlet有什么区别?
GenericServlet 为抽象类,定义了一个通用的、独立于底层协议的servlet,实现了 Servlet 和 ServletConfig 接口,ServletConfig接口定义了在Servlet初始化的过程中由Servlet容器传递给Servlet得配置信息对象。OK,这个类可能我们不是那么熟悉,但是他的子类相信大家都知道,也就是HttpServlet ,HttpServlet 继承自抽象类GenericServlet 具有其所有的特性并拓展了一些其他的方法,如doGet、doPost等。现在看到这俩方法都熟悉了吧。
2、什么情况下调用doGet()和doPost()呢?
也就是在前端代码中,如果我们的请求方式是get那就是doGet处理。同理post是doPost方法处理。
(1)doGet:GET方法会把名值对追加在请求的URL后面。因为URL对字符数目有限制,进而限制了用在客户端请求的参数值的数目。并且请求中的参数值是可见的,因此,敏感信息不能用这种方式传递。
(2)doPOST:POST方法通过把请求参数值放在请求体中来克服GET方法的限制,因此,可以发送的参数的数目是没有限制的。最后,通过POST请求传递的敏感信息对外部客户端是不可见的。
3、在这里没有提前端是jsp,是因为目前的前后端分离技术基本上jsp已经被淘汰了,JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
4、四种会话跟踪技术
客户端打开与服务器的连接发出请求到服务器响应客户端请求的全过程称之为会话 。浏览器与服务器之间的通信是通过HTTP协议进行通信的,而HTTP协议是”无状态”的协议,它不能保存客户的信息,即一次响应完成之后连接就断开了,下一次的请求需要重新连接,这样就需要判断是否是同一个用户,所以才应会话跟踪技术来实现这种要求。
(1)Cookie
(2)Session
(3)URL复写:把会话ID编码在URL中。
(4)隐藏表单域
5、会话作用域
(1)page域:数据在一个页面范围内有效,通过pageContext对象访问
(2)request域:数据在一个服务器请求范围内有效,通过request对象访问
(3)session域:数据在一次会话范围内容有效,通过session对象访问
(4)application域:数据在一个应用服务器范围内有效,通过application对象访问
6、Cookie和Session的作用和区别
(1)cookie 是一种发送到客户浏览器的文本串句柄,数据保存在客户端,可以用来在某个WEB站点会话间持久的保持数据。
(2)session技术中所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录或具有某种权限。
(3)cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。
(4)cookie 和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。
7、如何知道是哪一个客户端的机器正在请求你的Servlet
ServletRequest类可以找出客户端机器的IP地址或者是主机名。getRemoteAddr()方法获取客户端主机的IP地址,getRemoteHost()可以获取主机名。
8、HTTP响应的结构是怎么样的?
HTTP响应由三个部分组成:
(1)状态码(Status Code):描述了响应的状态。可以用来检查是否成功的完成了请求。请求失败的情况下,状态码可用来找出失败的原因。如果Servlet没有返回状态码,默认会返回成功的状态码HttpServletResponse.SC_OK。
(2)HTTP头部(HTTP Header):它们包含了更多关于响应的信息。比如:头部可以指定认为响应过期的过期日期,或者是指定用来给用户安全的传输实体内容的编码格式。如何在Serlet中检索HTTP的头部看这里。
(3)主体(Body):它包含了响应的内容。它可以包含HTML代码,图片,等等。主体是由传输在HTTP消息中紧跟在头部后面的数据字节组成的。
9、sendRedirect()和forward()方法有什么区别?
sendRedirect()方法会创建一个新的请求,而forward()方法只是把请求转发到一个新的目标上。重定向(redirect)以后,之前请求作用域范围以内的对象就失效了,因为会产生一个新的请求,而转发(forwarding)以后,之前请求作用域范围以内的对象还是能访问的。一般认为sendRedirect()比forward()要慢。
10、隐含对象是什么意思?有哪些隐含对象?
JSP隐含对象是页面中的一些Java对象,JSP容器让这些Java对象可以为开发者所使用。开发者不用明确的声明就可以直接使用他们。JSP隐含对象也叫做预定义变量。下面列出了JSP页面中的隐含对象:application、page、request、response、session、exception、out、config、pageContext。
此外,我在网上找了几套Servlet常见的面试题,基本上就是这些。