servlet&servletContext
今日内容:
[重点]Servlet(小程序)
[理解]ServletContext(域对象)
第1章 Servlet入门
1.1 Servlet2.5实现Hello world例子
-
什么是Servlet
Servlet表示服务端完成某个功能的小程序 本质Servlet是sun公司提供的规范(接口)
-
编写一个Servlet2.5的步骤
1)创建一个class实现servlet接口 2) 重写service方法 3) 创建的类必须在web.xml文件中做配置
-
servlet与普通的java程序的区别
a.Servlet实现类必须实现Servlet接口 b.Servlet不能独立运行,必须在(Serlvet容器中)服务器中运行 c.Servlet可以处理用户的请求(接收请求,给出响应)
-
代码实现servlet2.5
//1.实现类 public class MyServlet implements Servlet{ //2.重点关注:Service方法 @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("HelloWorld!!!!"); } } <!--配置Servlet--> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.itheima.demo01_Servlet_2_5.MyServlet</servlet-class> </servlet> <!--配置Servlet的路径--> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/abc</url-pattern> </servlet-mapping>
-
浏览器访问路径
http://localhost:8080/项目名/abc
1.2 Servlet3.0实现Hello world
-
Servlet2.5与Servlet3.0的区别
a.Servlet3.0以注解就可以替代Servlet2.5中web.xml配置文件 b.还有一些其他特点:比如异步处理特性,可插特性等....
-
编写一个Servlet3.0的步骤
1)创建一个class实现servlet接口 2) 重写service方法 3) 只需要使用一个注解,就可以替代web.xml配置文件
-
代码实现servlet3.0
//1.实现类 //3.添加注解,代替web.xml中的配置 @WebServlet(name = "MyServlet",urlPatterns = "/cba") public class MyServlet implements Servlet { //2.重点关注的方法 @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("HelloWorld Servlet!!"); } }
-
浏览器访问路径
http://localhost:8080/项目名/cba
第2章 Servlet生命周期
2.1 什么是生命周期
生命周期:从创建到销毁的过程
2.2 servlet生命周期相关的方法
a.init 初始化方法,Servlet创建时调用
b.service 服务方法,当浏览器访问时调用
c.destory 销毁方法,Servlet从服务器中卸载时调用
init方法什么时候调用??
第一次访问该Servlet时,调用init方法(只会在第一次时调用)
service方法什么时候调用??
每次访问该Servlet时,都会调用service方法(访问一次调用一次)
destory方法什么时候调用??
a.从服务器中把Servlet所在的项目卸载时,该Servlet调用销毁方法
b."正常关闭"服务器时,Servlet也会调用销毁方法
2.3 servlet生命周期流程
第3章 Servlet的体系结构
3.1 Servlet的体系结构概述
根接口: Servlet接口 (5个抽象方法)
实现类: GenericServlet(实现了Servlet接口)
实现类: HttpServlet(继承GenericServlet,把service方法,根据请求方法的不同,做了不同的方法)
public interface Servlet{
service等五个方法
}
public abstract class GenericServlet implements Servlet{
重写除了service之外的四个方法
只有一个抽象方法service方法
}
public class HttpServlet extends GenericServlet{
重写service方法,并且根据请求方式的不同,分别了多个方法(doGet/doPost)
if("请求方式".equals("get")){
doGet(); //调用doGet方法
}else if("请求方式".equals("post")){
doPost();//调用doPost方法
}else if("其他方式..."){
也会调用其他方法...
}
}
所以我们开发中,一般来说都使用继承HttpServlet的方式,然后重写doGet和doPost方法
3.2 servlet底层运行原理(画图)
浏览器访问:localhost:8080/day2203/mhs
服务器获取到浏览器的请求之后:
a.截取"/day2203",在服务器webapps中查询是否有该项目
b.截取"/mhs",在刚刚查出的项目中,查找"/mhs"这个路径的Servlet
c.创建该Servlet对象,调用init方法
d.创建两个对象,request对象(把浏览器请求的所有数据封装到其中),response对象(保存我们需要响应的数据)
e.调用service方法将request对象和response对象传入
f.如果项目卸载或者服务器正常关闭,调用Servlet的destory方法
第4章 Servlet的配置
4.1 url-pattern配置
-
一个servlet匹配多个路径
Servlet2.5在web.xml中配置 <!--配置Servlet--> <servlet> <servlet-name>OneServlet</servlet-name> <servlet-class>com.itheima.servlet.OneServlet</servlet-class> </servlet> <!--配置url--> <servlet-mapping> <servlet-name>OneServlet</servlet-name> <url-pattern>/one</url-pattern> </servlet-mapping> <!--配置url--> <servlet-mapping> <servlet-name>OneServlet</servlet-name> <url-pattern>/one1</url-pattern> </servlet-mapping> Servlet3.0在注解上配置 @WebServlet(name = "OneServlet",urlPatterns = {"/one","/one1"}) public class OneServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp){ doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp){ System.out.println("Servlet执行了...."); } }
-
三种常见的匹配方式
a.完全匹配 <!--配置TwoServlet--> <servlet> <servlet-name>TwoServlet</servlet-name> <servlet-class>com.itheima.servlet.TwoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TwoServlet</servlet-name> <url-pattern>/aaa/two</url-pattern> </servlet-mapping> 访问时:http://localhost:端口号/项目名/aaa/two b.目录匹配 <!--配置ThreeServlet--> <servlet> <servlet-name>ThreeServlet</servlet-name> <servlet-class>com.itheima.servlet.ThreeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ThreeServlet</servlet-name> <url-pattern>/bbb/*</url-pattern> </servlet-mapping> 访问时:http://localhost:端口号/项目名/bbb/任意路径 c.扩展名匹配 <!--配置FourServlet--> <servlet> <servlet-name>FourServlet</servlet-name> <servlet-class>com.itheima.servlet.FourServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FourServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> 访问时:http://localhost:端口号/项目名/..(随意).../xxx.action 注意:url-pattern不可以这么写!!!! /aaa/bbb/*.action(指定了扩展名匹配,就无法指定某个目录!!) 三种匹配方式的优先级: 完全匹配 > 目录匹配 > 扩展名匹配
-
缺省匹配:/(默认匹配方式)
<!--配置DefaultServlet--> <servlet> <servlet-name>DefaultServlet</servlet-name> <servlet-class>com.itheima.servlet.DefaultServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DefaultServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
4.2 load-on-startup配置
Servlet什么时候会创建??
第一次访问该Servlet时会创建,并会调用init方法
能否让Servlet跟随服务器启动完毕就创建出来??
可以的!!! 只要在配置该Servlet时,添加标签load-on-startup
<!--配置LifeCircleServlet-->
<servlet>
<servlet-name>LifeCircleServlet</servlet-name>
<servlet-class>com.itheima.servlet.LifeCircleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>LifeCircleServlet</servlet-name>
<url-pattern>/lcs</url-pattern>
</servlet-mapping>
注意:可以有多个Servlet都服务器启动完毕创建出来,标签load-on-startup的数值越小优先级越高
如果是Servlet3.0,在注解上配置随着服务器启动而创建Servlet
@WebServlet(name = "LifeCircleServlet",urlPatterns = "/lcs",loadOnStartup = 1)
第5章 Servlet的路径
5.1 三种路径的介绍
<body>
<%--带协议的绝对路径--%>
<a href="http://localhost:8080/day22/my">点我访问my</a><br/>
<%--不带协议的绝对路径--%>
<a href="/day22/my">点我访问my</a><br/>
<%--相对路径--%>
<%--当前页面: http://localhost:8080/day22/aa/index.jsp--%>
<%--Servlet: http://localhost:8080/day22/my--%>
<a href="../my">点我访问my</a><br/>
</body>
第6章 ServletContext对象
6.1 ServletContext的概述
什么是ServletContext: Servlet上下文对象(全局的域对象)
域对象: 就是一种容器(底层是一个Map集合)
全局的: 整个项目共享一个ServletContext域对象(每个项目都有一个自己的ServletContext对象)
6.2 获取初始化配置信息(了解)
-
在web.xml中配置初始化信息
<!--可以给项目配置一些初始化信息--> <context-param> <param-name>Encoding</param-name> <param-value>UTF-8</param-value> </context-param>
-
创建Servlet,通过ServletContext获取初始化信息
public class GetContextParamServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response){ //通过ServletContext域对象获取配置文件中全局项目的配置信息 ServletContext servletContext = getServletContext(); //获取信息 String value = servletContext.getInitParameter("Encoding"); //打印 System.out.println("Encoding = " + value); } }
-
配置Servlet
<!--配置GetContextParamServlet--> <servlet> <servlet-name>GetContextParamServlet</servlet-name> <servlet-class>com.itheima.servlet.GetContextParamServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>GetContextParamServlet</servlet-name> <url-pattern>/get</url-pattern> </servlet-mapping>
-
访问路径
http://localhost:8080/项目/get 控制台打印: Encoding = UTF-8
6.3 获取当前应用下的所有资源的路径(理解)
-
在当前项目下存在一些资源
-
创建一个Servlet,使用ServletContext获取当前项目下所有资源的路径
public class ReadResourceServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response){ System.out.println("ReadResourceServlet执行了...."); //需求:读取1.txt文件的内容 //1.获取ServletContext ServletContext servletContext = getServletContext(); //2.通过ServletContext获取1.txt真实的路径 String realPath = servletContext.getRealPath("/WEB-INF/2.txt");// 这里的/就是代表当前项目的根目录 //3.打印 System.out.println("文件的真实路径:"+realPath); } }
-
配置Servlet
<!--配置ReadResourceServlet--> <servlet> <servlet-name>ReadResourceServlet</servlet-name> <servlet-class>com.itheima.servlet.ReadResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ReadResourceServlet</servlet-name> <url-pattern>/read</url-pattern> </servlet-mapping>
-
浏览器访问
访问路径:http://localhost:8080/项目名/read 控制台输出: 文件的真实路径:E:\heima126\out\artifacts\day22_three_path_war_exploded\WEB-INF\2.txt
6.4 ServletContext作为域对象(重点)
什么是域对象: 就是一个容器(Map容器)
a.如何获取ServletContext域对象:
GenericServlet中的方法: getServletContext();
b.增删改查
1. void setAttribute(String name, Object object) 增加和修改
2. Object getAttribute(String name) 获取
3. void removeAttribute(String name) 删除
-
创建Servlet
@WebServlet(name = "OneServlet",urlPatterns = "/one") public class OneServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { //0.获取ServletContext ServletContext servletContext = getServletContext(); //1.向ServletContext中添加键值对 servletContext.setAttribute("name", "北京"); //2.从ServletContext获取name //String name = (String) servletContext.getAttribute("name"); //System.out.println("name = " + name); //3.修改name //servletContext.setAttribute("name", "南京"); //name = (String) servletContext.getAttribute("name"); //System.out.println("name = " + name); //4.删除name //servletContext.removeAttribute("name"); //name = (String) servletContext.getAttribute("name"); //System.out.println("name = " + name); } }
-
浏览器访问
http://localhost:8080/项目名/one 控制台输出: name = 北京 name = 南京 name = null
-
再创建一个Servlet,从域对象中取出数据
@WebServlet(name = "TwoServlet",urlPatterns = "/two") public class TwoServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { //1.从ServletContext全局的域对象中取出name数据 ServletContext servletContext = getServletContext(); String name = (String) servletContext.getAttribute("name"); //2.打印 System.out.println("在TwoServlet中取出数据name = "+ name); } }
-
浏览器访问
先访问:http://localhost:8080/day22/one 再访问:http://localhost:8080/day22/two 控制台输: 在TwoServlet中取出数据name = 北京
6.5 扩展案例-统计网站访问总次数
假设有两个Servlet:
CountServlet:给用户访问的Servlet,访问一次计数一次
ShowServlet:显示本次服务器启动后,一共被访问了多少次!
-
CountServlet:统计次数
/** * 统计访问次数的Servlet */ @WebServlet(name = "CountServlet",urlPatterns = "/count") public class CountServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { //1.获取全局域对象 ServletContext servletContext = getServletContext(); //2.获取number Object number = servletContext.getAttribute("number"); //3.判断 if (number == null) { servletContext.setAttribute("number",1); }else{ Integer num = (Integer) number; servletContext.setAttribute("number", num + 1); } //4.输出 response.getWriter().println("welcome to our!!!"); } }
-
ShowServlet:显示次数
@WebServlet(name = "ShowServlet", urlPatterns = "/show") public class ShowServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response){ //1.获取全局域对象 ServletContext servletContext = getServletContext(); //2.获取number Object number = servletContext.getAttribute("number"); //3.打印 response.getWriter().println("number = " + number == null ? 0 : number); } }
总结
"1.能够使用idea编写servlet 编写Servlet2.5使用web.xml 编写Servlet3.0使用@WebServlet 2.能够使用idea配置tomcat方式发布项目(昨天的内容) 3.能够使用注解开发servlet "4.能够说出servlet生命周期方法执行流程 init: 创建Servlet时调用(默认第一次访问创建,添加load-on-startup标签,可以开机启动) service: 每次访问Servlet时调用 destroy: 销毁Servlet时调用(正常关闭服务器或者卸载当前项目) 5.能够说出servlet运行原理 访问路径: http://localhost:8080/day22/my 首先:http://localhost:8080 找到服务器 其次:/day22 找到服务器中项目 再次:/my 找Servlet 最后:调用Servlet的service方法(doGet/doPost) "6.能够使用servletcontext域对象 a.获取web.xml中配置的项初始化参数 b.获取当前项目下所有资源的真实路径 c.(重点掌握)作为全局的域对象(增删改查) "7.能够完成案例统计访问次数"