为什么访问URL会执行到自定义的Servlet类中的方法呢?http://localhost 会到C:\Windows\System32\drivers\etc\hosts文件中去寻找localhost的对应ip地址127.0.0.1,接着找到8080端口,进入tomcat服务器,接着进入webapps下的Servlet工程下,关键是怎么着/first呢? 在Servlet工程中的web.xml中的url-pattern中查找是否有/first内容,如果有就成功的加载。 首先匹配servlet-mapping中url-pattern中查看,接着得到servlet-mapping中的servlet-name,从而去Servlet中查找servlet-name,从而得到servlet-class,servlet-class才是整个执行过程中最重要的部分。得到servlet-class文件的全名(实际上是一个字符串)之后,构造HttpServlet子类的对象,然后调用子类里面的方法(这个过程使用反射技术,只能通过反射才能实现)。 如果对反射的知识点不明确,请自行找资料解决。 Servlet映射路径Servlet的映射路径有servlet-mapping中的url-pattern(注意url-pattern要么要以/开头,要么要以*开头)决定,那么url-pattern究竟怎么写,怎么去匹配呢?有两种匹配方案: 精确匹配:/first(url-pattern) http://localhost:8080/Servlet工程名/first (浏览器中输入) 模糊匹配,下面三种方式,但是在一个url-pattern中不能组合下面的模糊匹配方式 /* 或者直接使用/ 在浏览器中输入:http://localhost:8080/Servlet工程/任意路径(不写都行) 但是请注意,在实际写url-pattern时不要使用这两个方式,这两个方式是Servlet的缺省(default)(tomcat服务器内置)路径,该路径可以在conf/web.xml中找到。缺省的Servlet是用于解析web的静态资源文件。 /jpzhu/* 在浏览器中输入:http://localhost:8080/Servlet工程/jpzhu/任意路径(不写都行) *.后缀名(后缀名可以随便取) 在浏览器中输入: http://localhost:8080/任意路径.后缀名 注意模糊匹配不能组合起来用,只能单个使用,例如:/jpzhu/*.do如果在浏览器中输入的url有多个Servlet同时被匹配,也就是说模糊匹配和精确匹配都能找到对应的Servlet资源,精确匹配的优先级高(长得最像的优先被匹配),但是要尽量避免这种情况的发生。当以后缀名结尾的模糊匹配,优先级最低。 Servlet映射练习对于如下的一些映射关系: Servlet1 映射到/abc/* Servlet2 映射到/* Servlet3 映射到/abc Servlet4 映射到*.do问题: 当请求URL为”/abc/a.html”,此时Servlet1和Servlet2都匹配,该是哪一个被最后匹配呢?Servlet1 当请求URL为”/abc”时,Servlet1、Servlet2、Servlet3都能被匹配,该是哪一个被最后匹配呢?Servlet3 当请求URL为”/abc/a.do”时,Servlet1和Servlet4都能被匹配,该是哪一个被最后匹配呢?Servlet1,因为*.do的优先级是最低的。 当请求URL为”/a.do”时,Servlet2和Servlet4都能被匹配,最后哪一个被正确的匹配呢?Servlet2,因为*.do的优先级最低。 当请求URL为”/xxx/yyy/a.do”时,Servlet2和Servlet4都能被匹配,最后哪一个被正确的匹配呢?Servlet2,因为*.do的优先级最低。我的理解:这个过程实际上是确实路由的路径,和Rails技术中的路由技术的原则是一样的。 解析URL的顺序:当输入一个URL时,首先会到web.xml文件中查找是否与偶匹配的url-pattern,如果能匹配到url-pattern,则处理,如果不能匹配到,则交给tomcat的default-servlet处理,也就是会去加载静态资源文件。 结论:先找动态资源,后找静态资源。 Servlet生命周期为什么要学习Servlet生命周期Servlet程序由tomcat服务器调用,所以有必要去知道究竟怎么去调用,Servlet生命周期就是要去搞明白Servlet对象什么时候去创建?调用什么方法?什么时候Servlet对象被销毁?销毁调用什么方法做了什么事情?Servlet程序的生命周期是由tomcat服务器去控制的。 Servlet重要的生命周期方法构造方法:创建Servlet对象时调用,所谓的创建Servlet对象是指第一次访问Servlet的时候。Servlet在tomcat服务器中是单实例对象。 模拟通过反射构造Servlet对象首先说明,该段代码只是对使用反射构造Servlet对象机制的模拟,该段代码并不需要我们自己去写,但是我们需要利用此段代码去明白一下所谓的反射机制。
Servlet单实例多线程Servlet对象会在请求第一次加载时建立该类的对象,只要没有服务器的重新启动或者资源的重新加载,都不会再去创建新的Servlet对象,所以我们可以知道Servlet对象是单实例的,但是一个常识就是不止一个人会发出同样的URL请求,此时只有一个Servlet对象,怎么去做呢?实际上Servlet中有多线程处理逻辑,这些代码也是不需要我们去写的。 Servlet是单实例多线程的,所以我们应该把共享数据和代码块进行同步(使用synchronized关键字进行同步)。 建议在Servlet中尽量不要使用成员变量,如果确实要使用成员变量,必须要同步,而且要尽量缩小同步代码块的范围(因为同步会导致效率变得十分的低下),原则上哪里使用到了成员变量就同步哪里,以避免因为同步而导致的并发效率低下。 Servlet留给开发者的init方法在Servlet接口以及其实现HttpServlet类中提供给了两个init方法,其函数原型分别如下:
实际上看查看Servlet的源代码,你会知道有参数的init方法会调用无参数的init方法,但是当我们重写(@Override)了有参数的init方法会导致tomcat服务器不调用无参数的init方法,实际上这个原理可以在Servlet编程中很方便的验证,因此我们的原则是在无参数的init方法中写我们的初始化逻辑。 Servlet中核心对象学习HttpServletRequest对象:请求对象,获取http请求信息 HttpServletResponse对象:响应对象,设置响应对象 ServletConfig对象:Servlet配置对象 ServletContext对象:Servlet上下文对象 HttpServletRequest对象在Http协议的讲解中已经学完。 HttpServletResponse对象在Http协议的讲解中已经学完。 ServletConfig对象总之,ServletConfig对象的作用就是去拿参数,和Properties配置文件的功能差不多。 ServletConfig对象的作用作用:该对象主要是用于加载Servlet的初始化参数。 Servlet初始化参数配置方法 /conf/web.xml中找到对象的Servlet对象,配置 ,该参数就是初始化参数。 自己配置的参数会通被封装到ServletConfig对象中,通过有参数的init方法传入。 使用this.getServletConfig()方法得到ServletConfig对象。这也符合不去覆盖有参数的init方法的原则。getServletConfig()方法是Servlet类自己提供的,我们无需去写。
ServletConfig对象的创建和获取创建时机:在创建完Servlet对象,在调用init方法之前,服务器会自动的创建。 ServletContext对象ServletContext对象被称为Servlet上下文对象,它表示一个当前的web应用环境,怎么理解呢?一个web应用中有且只有一个ServletContext对象。实际上ServletContext相当于该web应用中的web.xml。 ServletContext的创建和得到创建时机:加载web应用时创建该对象。并且该对象的创建是早于ServletConfig对象的。 ServletContext对象的核心APIgetContextPath() 得到当前web应用的路径,web应用路径说白了就是部署到tomcat服务器上运行的web应用的名称,通常用在请求重定向的资源名称中。 getInitParameter(String name) 得到web应用的初始化参数 getInitParameterNames() 得到web应用的初始化参数关于得到web应用的初始化参数,我们首先应该明白怎么去配置?同样是在web.xml文件中进行配置
上述两个方法的使用和ServletConfig中的该类方法使用是一样的。 setAttribute(String name,Object object) 和域对象有关的方法,用于保存数据 域对象作用是:保存数据,获取数据,可以在不通的动态资源之间共享数据 几乎天天会用该对象方法 getAttribute(String name) 用于获取共享数据 removeAttribute(String name) 删除共享数据 getRequestDispatcher(String path) 转发(类似于重定向) 其效果上相等于跳转,但是转发只能转发到当前应用内的资源,不能转发到该项目之外的资源,但是重定向能重定向到其他项目的资源中 getRealPath(String path) 如何在web应用中得到该应用的资源文件 getResourceAsStream(String path) 代码测试下面的代码展示在一个Servlet应用中重要的文件,其他的文件请自行生成并使用,主要侧重于功能性测试。 TestServletContext.java
This is my HTML page. |
|