JavaWeb学习__第3天__Servlet

1.概述

    Servlet是SUN公司提供的用于开发动态web资源的技术,本质上是一段java小程序,能够运行在Servlet容器(Tomcat)当中。
    开发一个动态web资源的步骤:
    1).写一个类实现Servlet接口,其实是继承GenericServlet(它是Servlet的一个实现类)
        先将Servlet包加入Classpath
        javac -d . FristServlet
    2).将编译好的带包的.class放到WEB-INF/classes下以外,还要配置web应用的 web.xml注册Servlet

<servlet>
	<servlet-name>FirstServlet</servlet-name>  -- 给Servlet起一个名字,仅仅是名字而已
	<servlet-class>com.itheima.FirstServlet</servlet-class> --  具体Servlet 的类全路径名,注意不是文件名
</servlet>
<servlet-mapping>
	<servlet-name>FirstServlet</servlet-name> -- 给哪个名字的Serlvet配置对外访问路径
	<url-pattern>/servlet/first</url-pattern> --  配置通过哪个路径去访问此Servlet
</servlet-mapping>

2.Servlet运行过程

    Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
    1).Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
装载并创建该Servlet的一个实例对象。 
    2).调用Servlet实例对象的init()方法。
    3).创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
    4).WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

3.Servlet的生命周期

    通常情况下,服务器会在Servlet第一次被调用时创建该Servlet类的实例对象(servlet出生);一旦被创建出来,该Servlet实例就会驻留在内存中,为后续请求服务;直至web容器退出,servlet实例对象才会被销毁(servlet死亡)。
    在Servlet的整个生命周期内,Servlet的init方法只有在servlet被创建时被调用一次。
    而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
    servlet被销毁前,会调用destroy() 方法。

4.Servlet接口的继承结构

    Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
    Servlet接口:定义了一个servlet应该具有的方法,所有的Servlet都应该直接或间接实现此接口
        GenericServlet:对Servlet接口的默认实现,通用Servlet,这是一个抽象类,其中的大部分方法都做了默认实现,只有service方法是一个抽象方法需要继承者自己实现
        HttpServlet:是GenericServlet的实现类,对HTTP协议进行了优化的Servlet,继承自GenericServlet类,并且实现了其中的service抽象方法,默认的实现中判断了请求的请求方式,并根据请求方式的不同分别调用不同的doXXX()方法。通常我们直接继承HttpServlet即可

5.细节

    1.将Servlet映射到一个Url上面被外界访问:

<web-app>
	<servlet>
		<servlet-name>AnyName</servlet-name>
		<servlet-class>HelloServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>AnyName</servlet-name>
		<url-pattern>/demo/hello.html</url-pattern>
	</servlet-mapping>
</web-app>
    2.使用*号通配符来进行配置,但是只能是下面两种固定的写法
        以/开通并以/*结尾的路径
        以*.后缀的方式配置的路径
        匹配原理:,哪个最像找哪个,*.后缀优先级最低。
    3.配置load-on-startup ,使Servlet随着服务器的启动web应用加载后立即创建

<servlet>
	<servlet-name>invoker</servlet-name>
	<servlet-class>
		org.apache.catalina.servlets.InvokerServlet
	</servlet-class>
	<load-on-startup>2</load-on-startup><!--使invoker这个Servlet在web应用创建的时候就被装载-->
</servlet>
    用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。 

    4.缺省Servlet
    如果将某个Servlet的对外访问路径配置为一根正斜杠,则这个Serlvet就是缺省Servlet了,特点是:其他Servlet都不处理的请求,由它来处理.
    注:其实,浏览器在访问静态资源、错误提示页面时,都是由conf/web.xml(爸爸web.xml)中配置的缺省Servlet在进行输出,所以平常自己就不要配置缺省Servlet,否则会导致静态资源、错误页面无法正确访问。
    5.线程安全
    由于默认情况下Servlet的对象在内存中只有一个,多个浏览器并发访问时可能具有线程安全问题,我们可以使用锁机制来解决线程安全问题,但是容易造成程序的阻塞,效率降低,也可以使用SingleThreadModel接口,但是这个接口并不能真的防止线程安全问题已经被废弃。
    所以,我们以后再设计Servlet时,应该尽量的不要使用类成员变量和静态成员变量,如果一定要使用,则还是要用锁机制来访问线程安全问题,但是要注意,尽量的晚锁,尽量的早开锁,减少程序阻塞的时间。

6.ServletConfig/ServletContext

    ServletConfig:代表当前Servlet在web.xml中的配置信息
    当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
    用途:(1)获取Servlet在web.xml中配置的名字
          (2)获取web.xml中配置的Servlet的初始化信息
          (3)获取ServletContext对象
    ServletContext:代表当前web应用,唯一对应当前web应用
    生命周期:服务器启动,web应用加载后,立即创建代表当前web应用的ServletContext对象,创建出来后驻留在内存中。当服务器关闭或web应用被移除出容器时,随着web应用的销毁,ServletContext对象销毁。
    获取方法:this.getServletConfig().getServletContext();
              this.getServletContext();
    一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
    ServletContext的应用:
    1). 在整个web应用范围内共享数据
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
    2).获取WEB应用的初始化参数
    在web.xml文件的根目录下,可以配置整个web应用的初始化信息

<context-param>
	<param-name>encode</param-name>
	<param-value>utf-8</param-value>
</context-param>
String encode = context.getInitParameter("encode");
利用ServletContext对象身上的方法,可以非常方便的获取这些信息,从而可以把一些信息配置在web.xml文件中了。

    3).实现请求转发
        this.getServletContext().getRequestDispatcher("/servlet/Demo9Servlet").forward(request, response);
    4).用来读取资源文件
    web应用中,读取文件时,如果使用 相对路径/绝对路径,则到tomcat/bin目录下去找资源
    如果使用 硬盘路径 ,可以找到文件,但是一旦换了一个发布环境,所有的路径可能都是错的
    使用ServletContext.getRealPath("") -- 此方法,会在传入的路径之前拼接当前web应用的硬盘路径,从而得到当前资源的硬盘路径,从而读取资源
    如果WEB应用里面有的类不是Servlet类,通过类加载器也可以帮我们加载资源:
        Classloader.getResource("").getPath();
        此路径要小心,当前程序从哪个目录加载类,这个方法就从哪个目录加载给定路径的资源







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值