91.什么是 Servlet?
Servlet 是用来处理客户端请求并产生动态网页内容的 Java 类。Servlet 主要是用来处理或者是存储 HTML 表单提交的数据,产生动态内容,在无状态的 HTTP 协议下管理状态信息。
92.说一下 Servlet 的体系结构。
所有的 Servlet 都必须要实现的核心的接口是 javax.servlet.Servlet。每一个 Servlet 都必须要直接或者是间接实现这个接口, 或者是继承 javax.servlet.GenericServlet 或者javax.servlet.http.HTTPServlet。最后,Servlet 使用多线程可以并行的为多个请求服务。
93.Applet 和 Servlet 有什么区别?
Applet 是运行在客户端主机的浏览器上的客户端 Java 程序。而 Servlet 是运行在 web 服务器上的服务端的组件。applet 可以使用用户界面类,而 Servlet 没有用户界面,相反,Servlet是等待客户端的 HTTP 请求,然后为请求产生响应。
94.GenericServlet 和 HttpServlet 有什么区别?
GenericServlet 是一个通用的协议无关的 Servlet,它实现了 Servlet 和 ServletConfig 接口。继承自 GenericServlet 的 Servlet 应该要覆盖 service()方法。最后,为了开发一个能用在网页上服务于使用 HTTP 协议请求的 Servlet,你的 Servlet 必须要继承自 HttpServlet。这里有 Servlet的例子。
95.解释下 Servlet 的生命周期。
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;
请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;
当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法。
init方法和destroy方法只会执行一次,service方法客户端每次请求Servlet都会执行。
Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中
96.doGet()方法和 doPost()方法有什么区别?
①get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
②get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用"?"连接,而各个变量之间使用"&"连接;post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指向URL;
③get传输的数据要受到URL长度限制(最大长度是 2048 个字符);而post可以传输大量的数据,上传文件通常要使用post方式;
④使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
97.什么是 Web 应用程序?
Web 应用程序是对 Web 或者是应用服务器的动态扩展。有两种类型的 Web 应用:面向表现的和面向服务的。面向表现的 Web 应用程序会产生包含了很多种标记语言和动态内容的交互的web页面作为对请求的响应。而面向服务的Web应用实现了 Web服务的端点(endpoint)。一般来说,一个 Web 应用可以看成是一组安装在服务器 URL 名称空间的特定子集下面的Servlet 的集合。
98.什么是服务端包含(Server Side Include)?
服务端包含(SSI)是一种简单的解释型服务端脚本语言,大多数时候仅用在 Web 上,用 servlet标签嵌入进来。SSI 最常用的场景把一个或多个文件包含到 Web 服务器的一个 Web 页面中。当浏览器访问 Web 页面的时候,Web 服务器会用对应的 servlet 产生的文本来替换 Web 页面中的 servlet 标签。
99.什么是 Servlet 链(Servlet Chaining)?
Servlet 链是把一个 Servlet 的输出发送给另一个 Servlet 的方法。第二个 Servlet 的输出可以发送给第三个 Servlet,依次类推。链条上最后一个 Servlet 负责把响应发送给客户端。
100.如何知道是哪一个客户端的机器正在请求你的 Servlet?
ServletRequest 类可以找出客户端机器的 IP 地址或者是主机名。getRemoteAddr()方法获取客户端主机的 IP 地址,getRemoteHost()可以获取主机名。
101.HTTP 响应的结构是怎么样的?
状态码(Status Code):描述了响应的状态。可以用来检查是否成功的完成了请求。请求失败的情况下,状态码可用来找出失败的原因。如果 Servlet 没有返回状态码,默认会返回成功的状态码 HttpServletResponse.SC_OK。
HTTP 头部(HTTP Header):它们包含了更多关于响应的信息。比如:头部可以指定认为响应过期的过期日期,或者是指定用来给用户安全的传输实体内容的编码格式。如何在 Serlet中检索 HTTP 的头部看这里。
主体(Body):它包含了响应的内容。它可以包含 HTML 代码,图片,等等。主体是由传输在HTTP 消息中紧跟在头部后面的数据字节组成的。
102.什么是 cookie?session 和 cookie 有什么区别?
Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式
Cookie 一般用来保存用户信息 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。
Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。
Cookie 数据保存在客户端(浏览器端),如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。只能存放字符串
Session 数据保存在服务器端。安全性更高,可以存放对象
浏览器和 Servlet 通信使用的是什么协议?
浏览器和 Servlet 通信使用的是 HTTP 协议。
什么是 HTTP 隧道?
HTTP 隧道是一种利用 HTTP 或者是 HTTPS 把多种网络协议封装起来进行通信的技术。因此, HTTP 协议扮演了一个打通用于通信的网络协议的管道的包装器的角色。把其他协议的请求掩盖成 HTTP 的请求就是 HTTP 隧道。
105.sendRedirect()和 forward()方法有什么区别?
转发是服务器行为,重定向是客户端行为。
转发(Forward) 通过RequestDispatcher对象的forward方法实现的。
request.getRequestDispatcher("login_success.jsp").forward(request, response);
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址。
forward:转发页面和转发到的页面可以共享request里面的数据
forward:一般用于用户登陆的时候,根据角色转发到相应的模块。
重定向(Redirect) 是利用服务器返回的状态码来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过 HttpServletResponse 的 setStatus(int status) 方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL。
redirect:不能共享数据。
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等
106.什么是 URL 编码和 URL 解码?
URL 编码是负责把 URL 里面的空格和其他的特殊字符替换成对应的十六进制表示,反之就是解码。
如何让页面做到自动刷新?
自动刷新不仅可以实现一段时间之后自动跳转到另一个页面,还可以实现一段时间之后自动刷新本页面。
Servlet中通过HttpServletResponse对象设置Header属性实现自动刷新
Response.setHeader("Refresh","5;URL=http://localhost:8080/servlet/example.htm");
其中5为时间,单位为秒。URL指定就是要跳转的页面(如果设置自己的路径,就会实现每过5秒自动刷新本页面一次)
如何解决servlet的线程安全问题?
Servlet不是线程安全的,多线程并发的读写会导致数据不同步的问题。
解决的办法是尽量不要定义name属性,而是要把name变量分别定义在doGet()和doPost()方法内。
多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。