本节内容:
- Servlet简介
- Servlet的API
- Servlet的配置
- ServletContext对象
一、Servlet简介
1. 什么是Servlet
Servlet是运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API 动态的向客户端输出内容。
Servlet规范:包含三个技术点。或者说是servlet的三大组件。
- servlet技术
- filter技术(过滤器)
- listener技术(监听器)
2. Servlet入门小例子
实现步骤:
(1)创建类实现Servlet接口
(2)覆盖尚未实现的方法(重点实现service方法)
(3)在web.xml进行servlet的配置
Eclipse创建一个“Dynamic Web Project”,在src下创建一个包,然后在包里新建一个Servlet,目前我们只实现service方法。service代码如下:
@Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("QuickStratServlet running...."); res.getWriter().write("QuickStratServlet running...."); }
WEB-INF/web.xml文件里添加配置:
<!-- servlet的类的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> </servlet> <!-- servlet的虚拟路径的配置 --> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
右键项目,"Run As"——>"Run On Server",然后浏览器访问"http://localhost:8080/project_name/quickStratServlet"
页面显示:
QuickStratServlet running....
Servlet访问过程:
我们在创建Servlet时,默认是实现Servlet接口,但是该接口要实现的方法有很多,有init(ServletConfig config),service(ServletRequest request,ServletResponse response),destroy()等。
所以在实际开发中,我们不会直接去实现Servlet接口,因为那样需要覆盖的方法太多, 我们一般创建类继承HttpServlet。
实现步骤:
(1)创建类继承HttpServlet类
(2)覆盖doGet和doPost
(3)在web.xml中进行servlet的配置
二、Servlet的API(生命周期)
1. Servlet接口中的方法
(1)init(ServletConfig config)
何时执行:servlet对象创建的时候执行。因为接下来要调用service方法,该方法不是静态的,需要一个对象来调用,这个对象就是tomcat服务器帮我们创建的。
ServletConfig : 代表的是该servlet对象的配置信息。
(2)service(ServletRequest request,ServletResponse response)
何时执行:每次请求,service方法都会执行。
ServletRequest :代表请求。认为ServletRequest内部封装的是http请求的信息。
ServletResponse :代表响应。认为要封装的是响应的信息。
(3)destroy()
何时执行:servlet对象销毁的时候执行。
2. HttpServlet类的方法
- init()
- doGet(HttpServletRequest request,HttpServletResponse response)
- doPost(HttpServletRequest request,HttpServletResponse response)
- destroy()
3. Servlet的生命周期
一般面试的时候会问这个。
(1)Servlet何时创建
默认第一次访问servlet时创建该对象。可以通过配置让servlet对象不是第一次访问的时候创建,而是在服务器一启动时就创建。
(2)Servlet何时销毁
服务器关闭,servlet就销毁了。
Servlet对象是存储在内存中,这个对象不是你创建的,而且tomcat服务器帮你创建的,你无法拿到它的引用。
(3)每次访问必然执行的方法
service(ServletRequest req, ServletResponse res)方法。
三、Servlet的配置
1. 基本配置
<!-- servlet的类的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> <!-- 初始化参数示例 --> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql:///mydb</param-value> </init-param> </servlet> <!-- servlet的虚拟路径的配置 --> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
其中url-pattern的配置方式有三种:
(1)完全匹配。访问的资源与配置的资源完全相同才能访问到。
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
(2)目录匹配 格式:/虚拟的目录../* *代表任意
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/aaa/bbb/ccc/*</url-pattern> </servlet-mapping>
(3)扩展名匹配 格式:*.扩展名
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>*.abcd</url-pattern> </servlet-mapping>
注意:第二种与第三种不要混用。比如:/aaa/bbb/*.abcd,这种配置方式是错误的。
2. 服务器启动实例化Servlet配置
Servlet何时创建:默认第一次访问时创建。
当在servlet的配置上,加上一个配置 <load-on-startup>,servlet对象就会在服务器启动时就创建。配置示例如下:
<!-- servlet的类的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> <!-- servlet在服务器启动时创建对象,默认是第一次访问时创建对象。该配置必须放在servlet所有配置的最下面。 --> <!-- 里面的数字1-5都可以。数字代表优先级,数字越小,优先级越高。在开发中,一般不要配置为1,配置为中间的数。 --> <load-on-startup>3</load-on-startup> </servlet>
3. 缺省Servlet
可以将url-pattern配置一个/,代表该servlet是缺省的servlet。
什么是缺省的servlet?
当你访问资源地址所有的servlet都不匹配时 ,缺省的servlet负责处理该请求。
其实,web应用中所有的资源的响应都是servlet负责,包括静态资源请求。
现在在WebContent下新建一个1.html,web.xml里的url-pattern只配置一个/,如下:
<servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
浏览器输入http://localhost:8080/web13/1.html访问,你发现是访问的结果不是1.html的内容,而是QuickStratServlet的返回结果。
而当我们注释了“缺省的servlet”配置,再次访问http://localhost:8080/web13/1.html就可以访问到1.html的内容了。这是为什么呢?打开tomcat配置文件conf/web.xml,这个web.xml是全局的web.xml,对在该tomcat下的所有web应用都适用,但是有个前提,如果全局的web.xml和web应用的web.xml里面某些配置有冲突,则使用web应用自己的web.xml里面的配置。打开tomcat全局的web.xml,查找"<url-pattern>/</url-pattern>",
<!-- The mapping for the default servlet --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
在找这个default对应的servlet:
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
所以在访问1.html的时候,其实找的是org.apache.catalina.servlets.DefaultServlet,并不是直接找的1.html这个文件。DefaultServlet去应用的目录下寻找1.html这个文件, 把1.html逐句输出。如果没有找到1.html,会返回一个页面,显示404。这个页面也是DefaultServlet帮我们输出的。
4. 欢迎页面
我们在访问一个网站时,经常像这么访问,比如访问localhost:8080/web13/,后面什么资源都不写,这个时候会自动去找index.html,index.jsp或者其他的资源。这些都是可以在web.xml中配置的。
如果在web应用的web.xml中没有配置<welcome-file-list></welcome-file-list>,你在访问localhost:8080/web13/时,这时就会去找tomcat全局的web.xml文件中该配置。
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list>
四、ServletContext对象
1. 什么是ServletContext对象
ServletContext代表是一个web应用的环境(上下文)对象(可以理解为就是代表web应用),ServletContext对象内部封装的是该web应用的信息。一个web应用只有一个ServletContext对象。
问题:一个web应用有几个servlet对象?多个。
ServletContext对象的生命周期?
创建:该web应用被加载(服务器启动或发布web应用,前提时服务器是启动状态)
销毁:web应用被卸载(服务器关闭,移除该web应用)
2. 怎样获得ServletContext对象
两种方式:
(1)ServletContext servletContext = config.getServletContext(); 一般不用这种,比较麻烦。因为这个config是servlet的init方法里才有的。
(2)ServletContext servletContext = this.getServletContext();
3. ServletContext的作用
(1) 获得web应用全局的初始化参数
web.xml中配置初始化参数。比如配置如下:
<context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param>
今后在学习spring的时候,spring加载配置文件,配置文件位置就可以通过类似上面的配置来配置。
通过context对象获得参数:
public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得ServletContext对象 ServletContext context = getServletContext(); //或者this.getServletContext() this代表当前对象,不写也可以。 //这个方法在当前类中没有,找它爸爸HttpServlet也没有,找爷爷找到了 //1、获得初始化参数 String initParameter = context.getInitParameter("driver"); System.out.println(initParameter); } }
(2)获得web应用中任何资源的绝对路径
方法:String path = context.getRealPath(相对于该web应用的相对地址);
public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得ServletContext对象 ServletContext context = getServletContext(); //2、获得a.txt b.txt c.txt d.txt的绝对路径。(这4个txt文件分别建在不同的目录) //发布时,tomcat下的webapps下,建一个文件夹名和项目名一一致。将项目下的WebConten下的全部资源放到WEB13目录下。 //String path = context.getRealPath(相对于该web应用的相对地址); //2.1 获得a.txt,a.txt建在WebContent目录下 String realPath_A = context.getRealPath("a.txt"); System.out.println(realPath_A); //2.2 获得b.txt,b.txt建在WEB-INF目录下 String realPath_B = context.getRealPath("WEB-INF/b.txt"); System.out.println(realPath_B); //2.3 获得c.txt,c.txt建在src目录下。src下面的源代码最终会被发布到WEB-INF/classes/目录下 String realPath_C = context.getRealPath("WEB-INF/classes/c.txt"); System.out.println(realPath_C); //2.4 获得d.txt。d.txt建在WEB13_servlet目录下。----获取不到 //补充另外一个获取路径的方法 //在读取src(classes) 下的资源时,还可以通过类加载器(专门加载classes下的文件的)。只是写的比较麻烦 //getResource() 参数是一个相对地址 相对classes String path = ContextServlet.class.getClassLoader().getResource("c.txt").getPath(); System.out.println(path); } }
(3)ServletContext是一个域对象
什么是域对象?什么是域?
域就是区域的意思,存储数据的区域就是域对象。
ServletContext域对象的作用范围:整个web应用(所有的web资源都可以随意向 servletcontext域中存取数据,数据可以共享)
【例子】:写两个Servlet,一个向ServletContext域对象中存数据,一个向ServletContext域对象中写数据。
public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得ServletContext对象 ServletContext context = getServletContext(); //3、域对象---向servletContext中存数据 context.setAttribute("name", "zhangsan"); } }
public class ContextServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //域对象---从servletContext中取数据 String attribute = (String) this.getServletContext().getAttribute("name"); System.out.println(attribute); } }
域对象的通用的方法:
- setAtrribute(String name,Object obj);
- getAttribute(String name);
- removeAttribute(String name);