Servlet 2

本文详细解析了Servlet在Tomcat服务器中的生命周期,包括构建、初始化、服务和销毁四个阶段,并介绍了自动加载、线程并发安全、初始化参数配置等核心概念。

通过伪代码演示servlet的生命周期(tomcat服务器中进行)

1)通过映射找到servlet-class的内容,字符串:cn.jinshuo.ServletDemo.FirstServlet

2)通过反射构造FirstServlet对象

        得到字节码对象:Class clazz=class.forName("cn.jinshuo.ServletDemo.FirstServlet");

        调用无参数的构造方法来构造对象:clazz.newInstance();       ----1.servlet的构建方法被调用

3)创建ServletConfig对象,通过反射调用init方法

        得到方法对象:Method m=clazz.getDeclareMethod("init",ServletConfig.class);

        调用方法:m.invoke(obj,config);                             ----2.servlet的init方法被调用

4)创建request,response对象,通过反射调用service方法

        得到方法对象 :Method m=clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

        调用方法:m.invoke(obj,request,response);   ----3.servlet的service方法被调用

5)当tomcat服务器停止或者web应用重新部署,通过反射调用destory方法

        得到方法对象:Method m=clazz.getDeclareMethod("destory",null);

        调用方法:m.invoke(obj,null);        ----4.servlet的destory方法被调用。

1、Servlet的自动加载:

在默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法执行了比较多的逻辑代码,那么导致用户第一次访问servlet的时候比较慢。

改变servlet创建对象的时机:提前到加载web应用的时候。

在servlet的配置信息中,加上一个<load-on-startup>即可。

<servlet>
    <!--servlet的内部名称,自定义。尽量有意义-->
    <servlet-name>FirstServlet</servlet-name>
    <!--serlvet的类全名:包名+简单类名-->
    <servlet-class>FirstServlet</servlet-class>
    <!--让servlet自动加载-->
    <load-on-startup>1</load-on-startup> 注意:整数值越大,创建时优先级越小。
</servlet>

 2、init方法

有参数的init方法
* 该方法是servlet的生命周期方法,它一定会被tomcat服务器调用。
* 不需要覆盖有参数的init方法。
无参数的init方法,自动被调用(只要没有覆盖有参数的init方法)
* 该方法是servlet的编写初始化代码的方法。是sun公司设计出来专门给开发者进行覆盖,
* 然后再里面编写servlet的初始化逻辑代码的方法。

3、线程并发安全

servlet对象在tomcat服务器中是单实例多线程的。

 

因为servlet是多线程的,所以当servlet的线程同时访问servlet的共享数据,如成员变量,可能引发线程安全问题。

解决办法:把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)。

      建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩短同步代码块的范围。(哪里使用到了成员变量,就同步哪里),以避免因同步而导致并发效率降低。

 

HttpServletRequest    请求对象:获取请求信息。

HttpServletResponse    响应对象:设置响应对象。

ServletConfig对象    servlet配置对象。

ServletContext对象    servlet的上下文对象。

4、servletconfig对象。

1>作用:ServletConfig对象:主要用于加载servlet的初始化参数。一个web中可以有多个servletconfig对象,一个servlet对应一个servletconfig

2>对象的创建的获得:

在创建完servlet对象之后,在调用init方法之前创建。

获得:直接从有参的init方法中得到

3>servlet的初始化参数配置

<servlet>
    <servlet-name>ConfigDemo</servlet-name>
    <servlet-class>ConfigDemo</servlet-class>
    <!--初始参数:这些参数会在加载web应用的时候,封装到ServletConfig对象中-->
    <init-param>
        <param-name>path</param-name>
        <param-value>e:/a.txt</param-value>
    </init-param>
</servlet>

servlet的参数只能由当前的这个servlet获取。

ServletConfig的API

      java.lang.String.getInitParameter(java.lang.String name)  根据参数获取参数值

      java.until.Enumeration.getInitParameterNames()    获取所有参数

      ServletContext.getServletContext()    得到servlet上下文对象

      java.lang.String.getServletName()    得到servlet的名称

//查询当前servlet的所有初始化参数
Enumeration<String> enums=this.getServletConfig().getInitParameterNames();
while(enums.hasMoreElements()){
    String paramName=enums.nextElement();
    String paramValue=this.getServletConfig().getInitParameter(paramName);
    System.out.println(paramName+"="+paramValue);
}

5、ServletContext对象:叫做servlet的上下文对象,表示一个当前的web应用环境。一个web应用中只有一个servletcontext

1>ServletContext对象的核心API

 java.lang.String getContextPath();  --得到当前web应用的路径
java.lang.String getInitParameter(java.lang.String name);  --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames();

void setAttribute(java.lang.String name,java.lang.Object object);  --得到域对象有关的方法
java.lang.Object getAttribute(java.lang.String name);
void removeAttribute(java.lang.String name);

RequestDispatcher getRequestDispatcher(java.lang.String path);  --转发(类似于重定向)

java.lang.String getRealPath(java.lang.String path);      --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path);

创建时间和得到:

时间:加载web应用时创建ServletContext对象

得到:从servletconfig对象的getServletContext方法得到

 1)创建ServletContext对象  ServletContext context=new ServletContext()
 2)创建ServletCofig对象  ServletConfig config=new ServletConfig();
                      config.setServletContext(context);
        class ServletConfig{
            ServletContext context;
            public ServletContext getServletContext(){
            return context;
            }
        }
        public void init(ServletConfig config){
        得到ServletConfig对象
        从ServletConfig中得到ServletContext
        ServletContext context=config.getServletContext();
        }

1>得到web应用的路径

java.lang.String getContextPath(); 用于请求重定向的资源名称中。

2>得到web应用的初始化参数(全局)

java.lang.String getInitParameter(java.lang.String name); --得到web应用的初始化参数

java.util.Enumeration getInitParameterNames();

web应用参数可以让当前web应用的所有servlet获取

3>域对象有关的方法

      域对象:作用是用于数据的保存、获取。可以在不同的动态资源之间共享数据。

案例:
Servlet1                                               Servlet2
name=eric
response.sendRedict("/Servlet2?name=eric")           String request.getParameter("name");
    保存到域对象中                                    从域中获取
student
方案1:可以通过传递参数的形式,共享数据。局限:只能传递字符串类型。
方案2:可以通过域对象共享数据,好处:可以共享任何类型的数据。

ServletContext就是一个域对象

保存数据:void setAttribute(java.lang.String name,java.lang.Object object);

获取数据:java.lang.Object getAttribute(java.lang.String name);

删除数据:void removeAttribute(java.lang.String name);

ServletContext域对象:作用范围在整个web应用中

      所有域对象:

              HttpServletRequest域对象

              ServletContext域对象

              HttpSession域对象

              Pagecontext域对象

4>转发:跳转页面

RequestDispatcher getRequestDispatcher(java.lang.String path);

1)转发

            a)地址栏不会改变

            b)不能转发当前web应用以外的资源

            c)可以在转发过程中把数据保存到request中

2)跳转

           a)地址栏变为重定向到的地址

           b)可以跳转到web应用内,或者其他web应用,甚至其他外部域名

           c)不能在重定向过程中把数据保存到request中。

结论:如果使用request域对象进行数据共享,只能使用转发技术。

得到web应用的资源文件
. 表示相对路径中的当前路径。相对于Java运行命令的目录
结论:
  在Java项目中, . 代表在Java项目的根目录下开始。
在JavaWeb项目中, . 代表tomcat的bin目录开始,所以不能使用这种相对路径。
File file = new File("./src/db.properties");

所以用:
this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");

得到web应用的资源文件的方法:
getRealPath(path);
java.io.InputStream getResourceAsStream(java.lang.String path);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值