前面咱们已经学过了Servlet的生命周期了,咱们根据Servlet的生命周期画出Servlet的调用图加深理解php
同一个Servlet能够被映射到多个URL上。web
<servlet> <servlet-name>Demo1</servlet-name> <servlet-class>zhongfucheng.web.Demo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>/Demo1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>/ouzicheng</url-pattern> </servlet-mapping>
不管我访问的是http://localhost:8080/Demo1仍是http://localhost:8080/ouzicheng。我访问的都是Demo1。数据库
通配符有两种格式:apache
匹配全部编程
匹配扩展名为.jsp的浏览器
若是*.扩展名和正斜杠(/)开头并以“/*”结尾两种通配符同时出现,匹配的是哪个呢?安全
*.
扩展名的优先级最低Servlet映射的URL可使用通配符和Servlet能够被映射到多个URL上的做用:服务器
<servlet> <servlet-name>Demo1</servlet-name> <servlet-class>zhongfucheng.web.Demo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>*.net</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>*.asp</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>*.php</url-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>Demo1</servlet-name> <servlet-class>zhongfucheng.web.Demo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
经过此对象能够读取web.xml中配置的初始化参数。
如今问题来了,为何咱们要把参数信息放到web.xml文件中呢?咱们能够直接在程序中均可以定义参数信息,搞到web.xml文件中又有什么好处呢?
好处就是:可以让你的程序更加灵活【更换需求,更改配置文件web.xml便可,程序代码不用改】
<servlet> <servlet-name>Demo1</servlet-name> <servlet-class>zhongfucheng.web.Demo1</servlet-class> <init-param> <param-name>name</param-name> <param-value>zhongfucheng</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>/Demo1</url-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中都配置一下,这样代码量太大了!而且会显得很是啰嗦冗余。
<context-param> <param-name>name</param-name> <param-value>zhongfucheng</param-value> </context-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");
第三种方式:
经过类装载器读取资源文件。
//获取到类装载器,2018年2月5日15:11:58 根据@兰兰美如画评论,发现Thread.currentThread().getContextClassLoader()这种方式会更好。 //ClassLoader classLoader = Servlet111.class.getClassLoader(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //经过类装载器获取到读取文件流 InputStream inputStream = classLoader.getResourceAsStream("3.png");
//获取到类装载器 ClassLoader classLoader = Servlet111.class.getClassLoader(); //经过类装载器获取到读取文件流 InputStream inputStream = classLoader.getResourceAsStream("/zhongfucheng/web/1.png");
原则:若是文件太大,就不能用类装载器的方式去读取,会致使内存溢出
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章的同窗,能够关注微信公众号:Java3y