前面我们已经学过了Servlet的生命周期了,我们根据Servlet的生命周期画出Servlet的调用图加深理解
同一个Servlet可以被映射到多个URL上。
<servlet>
<servlet-name>Demo1servlet-name>
<servlet-class>zhongfucheng.web.Demo1servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>/Demo1url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>/ouzichengurl-pattern>
servlet-mapping>
无论我访问的是http://localhost:8080/Demo1还是http://localhost:8080/ouzicheng。我访问的都是Demo1。
通配符有两种格式:
匹配所有
匹配扩展名为.jsp的
如果.扩展名和正斜杠(/)开头并以“/”结尾两种通配符同时出现,匹配的是哪一个呢?
Servlet映射的URL可以使用通配符和Servlet可以被映射到多个URL上的作用:
<servlet>
<servlet-name>Demo1servlet-name>
<servlet-class>zhongfucheng.web.Demo1servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>*.jspurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>*.neturl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>*.aspurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>*.phpurl-pattern>
servlet-mapping>
浏览器多次对Servlet的请求,一般情况下,服务器只创建一个Servlet对象,也就是说,Servlet对象一旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。
对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程。当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题。
原则:
如果在元素中配置了一个元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
作用:
当你启动Tomcat,你在网址上输入http://localhost:8080。为什么会出现Tomcat小猫的页面?
这是由缺省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>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Demo1servlet-name>
<servlet-class>zhongfucheng.web.Demo1servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
通过此对象可以读取web.xml中配置的初始化参数。
现在问题来了,为什么我们要把参数信息放到web.xml文件中呢?我们可以直接在程序中都可以定义参数信息,搞到web.xml文件中又有什么好处呢?
好处就是:能够让你的程序更加灵活【更换需求,更改配置文件web.xml即可,程序代码不用改】
<servlet>
<servlet-name>Demo1servlet-name>
<servlet-class>zhongfucheng.web.Demo1servlet-class>
<init-param>
<param-name>nameparam-name>
<param-value>zhongfuchengparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>Demo1servlet-name>
<url-pattern>/Demo1url-pattern>
servlet-mapping>
当Tomcat启动的时候,就会创建一个ServletContext对象。它代表着当前web站点
ServletContext对象可以被称之为域对象
到这里可能有一个疑问,域对象是什么呢?其实域对象可以简单理解成一个容器【类似于Map集合】
实现Servlet之间通讯就要用到ServletContext的setAttribute(String name,Object obj)方法,
第一个参数是关键字,第二个参数是你要存储的对象
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
String value = "zhongfucheng";
//MyName作为关键字,value作为值存进 域对象【类型于Map集合】
servletContext.setAttribute("MyName", value);
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过关键字获取存储在域对象的值
String value = (String) servletContext.getAttribute("MyName");
System.out.println(value);
如果我想要让所有的Servlet都能够获取到连接数据库的信息,不可能在web.xml文件中每个Servlet中都配置一下,这样代码量太大了!并且会显得非常啰嗦冗余。
param>
<param-name>nameparam-name>
<param-value>zhongfuchengparam-value>
param>
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过名称获取值
String value = servletContext.getInitParameter("name");
System.out.println(value);
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过名称获取值
String value = servletContext.getInitParameter("name");
System.out.println(value);
第一种方式:
FileInputStream fileInputStream = new FileInputStream("1.png");
System.out.println(fileInputStream);
FileInputStream fileInputStream = new FileInputStream("D:\\zhongfucheng\\web\\WEB-INF\\classes\\zhongfucheng\\web\\1.png");
System.out.println(fileInputStream);
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//调用ServletContext方法获取到读取文件的流
InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/zhongfucheng/web/1.png");
第二种方式:
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//调用ServletContext方法获取到读取文件的流
InputStream inputStream = servletContext.getResourceAsStream("2.png");
第三种方式:
通过类装载器读取资源文件。
//获取到类装载器
ClassLoader classLoader = Servlet111.class.getClassLoader();
//通过类装载器获取到读取文件流
InputStream inputStream = classLoader.getResourceAsStream("3.png");
//获取到类装载器
ClassLoader classLoader = Servlet111.class.getClassLoader();
//通过类装载器获取到读取文件流
InputStream inputStream = classLoader.getResourceAsStream("/zhongfucheng/web/1.png");
原则:如果文件太大,就不能用类装载器的方式去读取,会导致内存溢出