1、什么是Servlet
Servlet是用Java编写的服务端程序,它与协议和平台无关,运行于支持Java的应用服务器中,Java Servlet可以动态的扩展服务器的能力,并采用请求-响应模式提供web服务。最早支持Servlet技术的是javaSoft 的Java web server。此后一些其他的基于Java 的web server开始支持标准的Servlet API。Servlet的主要功能在于交互式地浏览和修改数据,生成动态Web内容。
2、Servlet交互式的浏览和修改数据,生成动态的web内容的过程
1)客户端发送请求信息到服务器端
2)服务器将请求信息发送到Servlet
3)Servlet生成响应内容并将其传给Server。响应内容动态生成,通常取决于客户端的请求
4)服务器将响应返回给客户端
3、Servlet的优势
1)Servlet可以和其他的资源比如说:文件、数据库、Applet、Java应用程序交互,以生成返回给客户端的响应内容。如果需要,还可以保存请求-响应过程中的信息;
2)采用Servlet 可以完全授权对本地资源的访问(如数据库),并且Servlet自身将会控制外部用户的访问数量及访问性质;
3)Servlet可以是其他服务的客户端程序例如,它们可以用于分布式的应用系统中,可以从本地硬盘,或者通过网络从远端硬盘激活Servlet;
4)Servlet可被链接(chain)。一个Servlet可以调用另一个或一系列Servlet,即成为它的客户端;
5)采用 Servlet Tag技术,可以在HTML页面中动态调用Servlet;
6)Servlet 独立于平台和协议;
7)Servlet 提供了Java应用程序的所有优势——可移植、稳健、易开发。使用Servlet 的Tag技术,Servlet能够生成嵌于静态HTML页面中的动态内容;
8)一个Servlet被客户端发送第一个请求激活,然后它将继续运行于后台,等待以后的请求,每个请求将生成一个新的线程,而不是一个完整的进程。多个客户能够在同一个进程中同时得到服务。一般来说,Servlet进程只是在Web Server卸载时被卸载;
4、谈谈对Servlet独立于平台和协议的理解
1)Servlet 是一种服务器端的Java应用程序,Java语言具有平台无关性,所以说Servlet独立于平台。Java Servlet API定义了一个 Servlet和Java使能服务器(Servlet 容器)之间的一个标准接口,这使得Servlet具有跨平台的特性。
2)Servlet不对具体的协议实现,可以接受自定义协议,常用的WEB项目HttpServlet 是对HTTP协议的实现,我们可以像HttpServlet一样扩展GenericServlet 来实现FtpServlet,TelnetServlet等
备注(了解): Java httpServlet和GenericServlet类的区别:httpServlet是GenericServlet的子类,GenericServlet是个抽象类,必须给出子类才能实例化。它给出了设计servlet的一些骨架,定义了servlet生命周期,还有一些得到名字、配置、初始化参数的方法,其设计的是和应用层协议无关的,也就是说你有可能用非http协议实现它(其实目前Java Servlet还是只有Http一种)。
HttpServlet是子类,当然就具有GenericServlet的一切特性,还添加了doGet, doPost, doDelete, doPut, doTrace等方法对应处理http协议里的命令的请求响应过程。一般没有特殊需要,自己写的Servlet都扩展HttpServlet
5、Servlet的生命周期
粗粒度理解Servlet的声明周期:
1)装载Servlet,一般是动态执行的。然而Server(服务器)通常会提供一个管理的选项,用于在Server启动时强制装载和初始化特定的Servlet
2)Server(服务器)创建一个Servlet的实例
3)Server调用Servlet的init()方法
4)一个客户端发送请求到server(服务器),服务器会创建一个request(请求对象)和response响应对象,server(服务器)激活Servlet的service()方法,传递请求和响应对象作为参数。
备注: service()方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息,service()方法使用响应对象的方法,将响应传回给Server,最终到达客户端,service()方法可能激活其他方法以处理请求,如doGet()和doPost()或程序员开发的新方法
5)对于更多客户端的请求,Server创建新的请求和响应对象,仍然激活此Servlet的Server()
方法,将两个对象作为参数传递给它如此重复以上的循环,但无需再次调用init()方法。如此重复以上的循环,但无需再次调用init()方法。,当Server不再需要Servlet时(一般当Server关闭时),Server调用Servlet的Destroy()方法。
细粒度理解Servlet的生命周期:
1)用户在浏览器地址栏上输入 URL:http://localhost:8080:/prj-servlet-03/testLifeCycle
2) web容器的截取请求路径:/prj-servlet-03/testLifeCycle;
3) web容器在容器上下文中找请求路径/prj-servlet-03/testLifeCycle对应的servlet对象;
4)若没有找到对应的Servlet对象则
4.1)通过web.xml文件中相关的配置信息,得到请求路径/testLifeCycle对应的Servlet完整类名
4.2)通过反射机制,调用Servlet类的无参数构造方法完成Servlet对象的实例化
4.3)web容器调用Servlet对象的init方法完成初始化的操作
4.4)web容器调用Servlet对象的service方法提供服务;
5)若找到找到对应的Servlet对象
5.1)web容器直接调用Servlet对象的Service方法提供服务;
6)web容器关闭的时候或者webapp重新部署的时候或者该Servlet对象长时间没有用户访问的时候web容器会将该Servlet对象销毁,在销毁该对象之前,web容器会调用Servlet对象的destory方法完成销毁之前的准备。
6、Java web程序员需要做什么
Server(服务器)和Servlet(sun公司的接口)这些都有不用你写,程序员值需要做:
1) 写一个类是实现Servlet接口(sun公司提供的)
2) 把这个类和路径写到配置文件中,服务器会自动调到这个类里面的方法
7、Web应用中涉及到的路径
1) html页面的超链接路径:
<html> <head> <title>welcome page</title> </head> <body> <a href="/prj-servlet-02/system/list">显示员工信息</a> 或者 <form action=”/项目名字/资源路径名”> 备注:该路径必须以“/”开始,需要添加工程的名字,/system/list必须和web.xml文件中配置的<url-pattern>/system/list</url-pattern>的路径一直。 </body> </html>
2) web.xml文件中的
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app 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_3_0.xsd" version="3.0"> <!--这是一个合法的web.xml文件--> <!--一个webapp只有一个web.xml文件--> <!--web.xml文件主要配置请求路径和servlet类之间的绑定关系--> <!--web.xml文件解析失败,会导致webapp启动失败--> <!--web.xml文件中的标签不能随便编写,因为tomcat服务器早就知道该文件中编写了哪些标签--> <!--web.xml文件中的标签也是sun公司制定的Servlet规范--> <!--<servlet>中的<servlet-name>中的名字和<servlet-mapping>中的<servlet-name>必须一样但是可以随意命名子--> <servlet> <servlet-name></servlet-name> <serlvet-class>com.bjpowernode.javaweb.servlet.ListEmpServlet</serlvet-class> 备注:如有包名的话,需要添加包的全部路径 <load-on-startup>2</load-on-startup> 该数值越小优先级越高 <serlvet> <servlet-mapping> <serlvet-name></servlet-name> <url-pattern>/system/list</url-pattern> 备注:路径的名字可以随意编写,必须以“/”开始,次此处不需要写项目/oa的名字,该路径即为html文件中href的路径,这个路径是一个虚拟的路径,只是代表一个资源的名称,也就是ListEmpServlet这个类的代号 </serlvet-mapping> <welcome-file-list> <welcome-file>资源路径</welcome-file> <!——备注:此处的资源路径名字前面没有/ ——> </welcome-file-list> </web-app>
3) 转发和重定向的路径:
重定向:response.sendRedirect("/项目名/资源路径");
转发:request.getRequestDispatcher("/资源路径").forward(request,response);
4) Cookie设置path
Cookie.setPath(“/项目名/资源路径”);cookie是将回话的状态保存在客户端、HttpSession是将回话的状态保存在服务器端,session不止在Java中有,只要是b/s架构的,不管什么语言,都有Session这种机制
5) ServletContext
ServletContext application=config.getServletContext();
application.getRealPath("/资源路径");//此处的资源也不需要加项目名
备注:设计到路径的常见的是:超链接、form表单、重定向、转发、Servlet路径、欢迎页面、Cookie设置path
更多提交请求的方法可参看博文:https://www.cnblogs.com/jiarui-zjb/p/9477498.html
8、html文件的部署和访问
1)html文件需要部署后才能访问,部署:将该项目放置到tomcat7/webapps目录下面就是部署完成
2)要启动tomcat7服务器后才能访问,访问:http://loacalhost:8080/项目的名称/*.html
备注:网址也就是url:统一资源定位符
协议://ip:端口号/uri(统一资源标示符)
url:可以定位,uri:只是网络中某个资源的名称,通过uri不可以定位
9、xml的作用
1)设计xml的主要作用是数据交换,也可以保存数据
2)xml保存数据具有平台无关,规范化,通过提供方提供的读取程序就可以读出xml数据
缺点:一个标签需要一个匹配的结束标签,比较冗余,其他的数据交换格式还有json,yaml等
10、Servlet接口中的方法
1) getServletConfig()返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init 方法的对象;
2) init(ServletConfig config) throws ServletException
由 servlet 容器调用,指示将该 servlet 放入服务。servlet 容器仅在实例化 servlet 之后调用 init 方法一次。在 servlet 可以接收任何请求之前,init 方法必须成功完成。Config:包含 servlet 的配置和初始化参数的 ServletConfig 对象;
3) getServletInfo() 返回有关 servlet 的信息,比如作者、版本和版权。此方法返回的字符串应该是纯文本,不应该是任何种类的标记(比如 HTML、XML等)
4)service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException
由servlet 容器调用,以允许 servlet 响应某个请求。此方法仅在 servlet 的 init() 方法成功完成之后调用。servlet 通常运行在可同时处理多个请求的多线程 servlet 容器中。开发人员必须知道要同步对所有共享资源(比如文件、网络连接以及 servlet 的类和实例变量)的访问。
5)destroy()
由 servlet 容器调用,指示将从服务中取出该 servlet。此方法仅在 servlet 的 service 方法已退出或者在过了超时期之后调用一次。在调用此方法之后,servlet 容器不会再对此 servlet 调用 service 方法。此方法为 servlet 提供了一个清除持有的所有资源(比如内存、文件句柄和线程)的机会,并确保任何持久状态都与内存中该 servlet 的当前状态保持同步。
备注:Servlet接口中的这些方法填写什么代码,什么时候使用这些方法
1) Servlet类的无参构造方法只执行一次;(执行的时候对象正在创建)
不建议将代码编写到构造函数中,当程序员编写构造方法时,可能会导致无参数构造方法不存在;一个类不编写任何的构造函数,默认有一个无参数的构造方法,但是一旦编写一个有参数的构造方法,系统则不再提供无参数构造函数;
2)Servlet对象的init方法只执行一次;(init方法执行的时候,Servlet对象已经被创建好了)
若系统要求在对象初始化时刻执行一段特殊的程序,这段程序尽量写到init方法中,servlet中的init方法是sun公司为Javaweb程序员专门提供的一个初始化时刻,希望在初始化时刻执行一段特殊的程序,这个程序可以编写到init方法,将来会被自动调用;
2) Servlet对象的service方法,只要用户请求一次,则执行一次;
该方法时必然要重写的,因为要在该方法中完成业务逻辑的处理、以及完成响应,而且该方法中的代码是最有价值的,也是最难写的。因为最难编写的就是业务代码;
3) Servlet对象的destory方法只执行一次;
(destory方法执行的时候,Servlet对象还没有被销毁,而是将被销毁)该方法也是sun公司为Javaweb程序员提供一个特殊的时刻,这个特殊时刻被称为对象销毁时刻,若希望在对象销毁时刻执行一段特殊代码,需要将这段代码编写到desstory方法,自动被容器调用;
Servlet对象是单例,但是不符合单例模式,只能成为伪单例,真单例的构造方法是私有的,Tomcat服务器是支持多线程的,所以Servlet对象是在单实例多线程的环境下运行的,那么Servlet对象中若有实例变量,并且实例变量涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题。不建议在Servlet对象中使用实例变量,尽量使用局部变量;
相关知识:静态代码块在类加载时执行,所以要在类加载时执行的程序要放在静态代码块中,例如:把类加载时的日期记录到日志里面。
11、开发一个web项目的顺序
新建一个web工程,并起好:工程的名字
1) index.html:
<a href=”/工程的名字/虚拟路径名”></a>
备注:虚拟路径名可以随便起
2) web.xml:
选中index.html文件中的:“/虚拟路径名”粘贴到:
<url-pattern>/虚拟路径名</url-pattern>
3) 创建一个Servlet,并进行代码的编写
4) 新建:文件名.html 用于对servlet处理的结果进行显示
备注:<url-pattern>编写的几种方式:
url-pattern可以编写多个
A:精确匹配
<url-pattern>/hello</url-pattern>
B:扩展匹配
<url-pattern>/abc/*</url-pattern>
C:后缀匹配
<url-pattern>/*.action</url-pattern>
<url-pattern>/*.do</url-pattern>
D:全部匹配
<url-pattern>/*</url-pattern>
12、Cookie相关处理
1)Cookie的存在是HTTP协议规定的,主要用来做身份认证和回话状态保留的
--Cookie保存在浏览器客户端上面的
--Cookie保存在浏览器的缓存中,浏览器关闭Cookie失效
--Cookie保存在客户端的硬盘上面,浏览器关闭Cookie还在,除非Cookie失效
--Cookie可以保存回话的状态,但是这个回话状态是保留在客户端上面的,Cookie清除或者失效这个回话状态就没有了。
--Java中Cookie被当做一个类来处理,可new Cookie()以保存回话的状态,但是这个回话状态只能保存在浏览器客户端,当换一个浏览器或者电脑的时候这个状态就没有了。
备注:默认情况下,服务器发送Cookie给浏览器之后,浏览器将Cookie保存在缓存当中,只要不关闭浏览器,Cookie永远存在,并且有效,当浏览器关闭之后,缓存中的Cookie被清除。
2)Cookie的特点:
--有效时间:决定于其存储位置(存储在缓存里还是硬盘上)
--Cookie跟路径有关系
-- response.addCookie(cookie1); 把Cookie从服务器发送给浏览器
-- Cookie[] cookies=request.getCookies(); 接受浏览器发送的Cookie
--浏览器禁用Cookie的意思是:服务器发送过来的Cookie浏览器不要或者说不接受,服务器还是会发送Cookie的只是浏览器不再接受。
3)浏览器关闭之后,服务器对应的Session对象不会被服务器销毁,因为B/S的架构是基于http协议的,而http协议是一种无连接、无状态的协议。
备注:Session对象在什么时候会被销毁:web系统中引入了Session超时的概念,当很长一段时间(这段时间可以配置),没有用户再访问session对象,此时的session对象超时,web服务器自动回收Session对象。在web.xml中默认是30分钟,实际开发的过程中多数配置成2小时,表示2个小时内没有人再访问就销毁该Session对象。
<servlet-config>
<session-timeout>120</session-timeout>此处填写的是分钟数
</servlet-config>
4) 什么是一次回话:
-- 一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束
-- 本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义上的一次完整会话。
5) ServletContext、HttpSession、HttpServletRequest接口的对比:
A:以上都是范围对象:
ServletContext application;是应用范围
HttpSession session;是会话范围
HttpServletRequest request;是请求范围
B:三个范围的排序:
application>session>request
C:application完成跨会话共享数据
session完成跨请求共享数据,但是这些请求必须在统一个会当中
request完成跨servlet共享数据,但是这些Servlet必须在统一个请求当中【转发】
D:使用原则:有小到大尝试
越小越好,越小耗费的资源越小,优先使用小范围;
例如向跨请求传递数据的话:
ServletContext:可以完成跨请求共享数据,不是说不安全,是所有用户共享的。
HttpSession:是一个用户一个,
HttpServletRequest:一次请求一个。
例如:登录成功之后,已经登录成功的状态需要保存起来,可以将登录成功的这个状态保存到session对象中登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象登录成功的状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享
备注:只要会话不关session永远之后一个,session中保存的数据你永远都能访问。只要你浏览器不关,你一直都能够访问。当你的浏览器关闭之后,你的session会话会超时,超时之后会自动销毁,销毁之后下次再访问就必须登录了。因为你的Session里面没有东西。
6)补充HttpServletRequest中的方法:
-- HTTPSession session=request.getSession();获取当前的session,获取不到,则新建session
-- HttpSession session=request.getSession(true);获取当前的session,获取不到则,新建Session
-- HTTPSession session=request.getSession(false);获取当前的session,获取不到,则返回null;
13、HTTP协议的主要特点
1)支持客户/服务器模式。
2)简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3)灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记。
4)无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5)无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
备注(了解):HTTP 协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求“点到为止”不会造成不必要连接占用,缺点在于每次请求会传输大量重复的内容信息。客户端与服务器进行动态交互的 Web 应用程序出现之后,HTTP 无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了。
与 Cookie 相对的一个解决方案是 Session,它是通过服务器来保持状态的。当客户端访问服务器时,服务器根据需求设置 Session,将会话信息保存在服务器上,同时将标示 Session 的 SessionId 传递给客户端浏览器,浏览器将这个 SessionId 保存在内存中,我们称之为无过期时间的 Cookie。浏览器关闭后,这个 Cookie 就会被清掉,它不会存在于用户的 Cookie 临时文件。以后浏览器每次请求都会额外加上这个参数值,服务器会根据这个 SessionId,就能取得客户端的数据信息。如果客户端浏览器意外关闭,服务器保存的 Session 数据不是立即释放,此时数据还会存在,只要我们知道那个 SessionId,就可以继续通过请求获得此 Session 的信息,因为此时后台的 Session 还存在,当然我们可以设置一个 Session 超时时间,一旦超过规定时间没有客户端请求时,服务器就会清除对应 SessionId 的 Session 信息。
14、Servlet对象和url-pattern和对应的完整类名存储
1) Servlet 对象实例化之后,Servlet对象如何存储:
大多数的web容器都是将该Servlet对象以及对应的url-pattern存储到map集合中
Map<String,Servlet>集合
-----------------------
key value
/login loginServlet对象引用
/delete DeleteServlet对象引用
/saveSaveServlet对象引用
……
2) web.xml文件中的url-pattern和对应的完整类名是如何存储的:
服务器在启动的时候就会解析各个webapp(web应用程序)的web.xml文件,并将url-pattern和其对应的Servlet完整的类名存储到map中
Map<String,String> 集合
key value
-----------------------------
/login com.bjpowernode.javaweb.servlet.LoginServlet
/delete com.bjpowernode.javaweb.servlet.deleteServlet;
……