web开发(五)ServletContext对象、作用、注解开发

1.1 什么是ServletContext

ServletContext:Servlet的上下文对象。ServletContext对象对Servlet之前和之后的内容都知道。有一个web项目就有一个ServletContext对象(web项目对象)。在服务器启动的时候为每个web项目创建一个单独的ServletContext对象。
ServletContext本身是一个接口,接口的实现类对象由Tomcat引擎提供
获取方式:

	方法1.先获取ServletConfig对象,在通过ServletConfig对象中的方法getServletContext获取
		ServletConfig config = getServletConfig();
		ServletContext context1 = config.getServletContext();
	方法2.在父类中GenericServlet中直接封装好了获取ServletContext对象的方式,我们可以直接使用
		ServletContext getServletContext()
		ServletContext context2 = getServletContext()

extends HttpServlet,HttpServlet extends GenericServlet,在GenericServlet里封装了方法getServletContext()。其实上面的两种方法的本质是一样的。
在这里插入图片描述

1.2 ServletContext对象的作用

1.2.1 用来获取web项目信息

因为一个web项目只有一个ServletContext对象,所以这个对象对整个项目的相关内容都是了解的。

方法 返回值 描述
getMimeType(String file) String 获取文件的MIME类型
getContextPath() String 获取web项目请求工程名
getInitParameter(String name) String 获取web项目的初始化参数
getInitParameterNames() Enumeration 获取web项目的初始化参数(返回类型是枚举)
举例说明:
package com.ccc.demo01ServletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet(urlPatterns = "/Context1")
public class Demo01ServletContext extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	    //在父类中GenericServlet中直接封装好了获取ServletContext对象的方式,我们可以直接使用
        ServletContext context = getServletContext();
        
        //String getMimeType(String file) 获取文件的MIME类型
        String aMimeType = context.getMimeType("a.txt");
        System.out.println(aMimeType);	//text/plain

        //String getContextPath() 获取web项目请求工程名
        String contextPath = context.getContextPath();
        System.out.println(contextPath);//    /day12_web

        //String getInitParameter(String name) 获取web项目的初始化参数值
        String a = context.getInitParameter("a");
        System.out.println(a);	//123

        //Enumeration<E> getInitParameterNames() 获取web项目的所有初始化参数的名称
        Enumeration<String> en = context.getInitParameterNames();
        while (en.hasMoreElements()){
            String name = en.nextElement();
            String value = context.getInitParameter(name);
            System.out.println(name+"\t"+value);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

1.2.2 获取WEB应用程序下任意资源的绝对路径

  • 方法: String getRealPath(“资源相对路径”),返回的是资源的绝对路径(在Tomcat服务器中的路径,包含盘符)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //context对象,方法getRealPath获取任意资源的绝对路径
      //获取web目录下的a.txt绝对路径
      String aPath = context.getRealPath("a.txt");
      System.out.println(aPath);
  
      //获取web目下WEB-INF目录下的b.txt绝对路径
      String bPath = context.getRealPath("WEB-INF/b.txt");
      System.out.println(bPath);
  
      //获取src目录下的c.txt绝对路径
      String cPath = context.getRealPath("WEB-INF/classes/c.txt");
      System.out.println(cPath);
  
      //获取WEB03 module下的d.txt绝对路径,获取不到,因为只有发布在Tomcat中的文件,才能获取到。
      //此时文件存在根目录下,不会发布到Tomcat中(即是在src文件夹之下),所以也就获取不到。
}

需要注意的是,这个方法它自身不会判断文件的真实性。只会使用字符串的拼接(项目路径+目录),而文件存在与否及这个路径是否正确,它并不会判断。
web中的项目是要发布到Tomcat中的,所以相对路径指的是相对于Tomcat,而Java项目是相对于Java的根目录的。

1.2.3 域对象

ServletContext对象是一个容器,可以存储数据.
对象有个作用域问题,ServletContext作用域是整个WEB应用程序
在这里插入图片描述

  • 向域对象存储数据: setAttribute(String key, Object value)
  • 取出域对象数据: Object getAttribute(String key)
  • 移除域对象数据: removeAttribute(String key)

以上的这三个方法(存储、取出、移除)同样适用于其他域对象

注意:

ServletContext对象作用域是整个web项目,即这个web项目里的所有Servlet都可以访问

扩展:(下面是按作用域由大到小排名)

  1. ServletContext:作用域时整个web项目;即这个web项目里的所有Servlet都可以访问。
  2. Session:只要浏览器不关闭就有效。就算是访问不同的虚拟地址也可以。但只能保留30分钟。
  3. Request:只要是地址栏不变,不刷新,就有效,即只能请求一次。转发也有效。但是重定向就无效了。因为转发的地址栏不变,重定向的地址栏发生变化了。
  4. PageContext:只在jsp本页面有效。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      /*
       * 域对象的存储和取出
       */
      ServletContext context = getServletContext();
      //域对象存储数据,键值对(在该项目的任意一个servlet中都能获取到该键值对)
      context.setAttribute("heima","java");
      //取出域对象存储的键值对
      Object value = context.getAttribute("heima");
      System.out.println(value);
      //移除域对象数据:  void removeAttribute(String key)
      context.removeAttribute("heima");
}

1.2.4 init方法只会在创建Servlet对象的时候执行一次

利用这个特点,我们可以先将init方法重写,然后把一些需要只执行一次的代码放到init方法里面。但是切记:一定要重写空参数的init方法,因为tomcat在调用完带参init方法之后,会默认调用空参数的(在源码中)。
以下是源码:
在这里插入图片描述
源码tomcat在调用完带参init方法之后,会调用空参数init方法。

@WebServlet(urlPatterns = "/context5")
public class Demo05ServletContext extends HttpServlet {
    //重写父类GenericServlet中init方法
    /*
        以后我们重写init方法,不要重写带ServletConfig的init方法
        重写空参数的init方法-->tomcat在调用完带参init方法之后,会调用空参数的
     */
    @Override
    public void init() throws ServletException {
        System.out.println("init方法只会在创建Servlet对象的时候执行一次");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext域对象
        ServletContext context = getServletContext();
        System.out.println(context);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

引发问题:ServletContext对象的空指针异常

在这里插入图片描述

产生原因:

重写父类GenericServlet中的init的带参方法后。在程序运行的时,它就会优先调用重写后的这个init方法。

解决方案:

以后我们重写init方法时,不要重写带参数(ServletConfig config)的方法。要重写空参数的init方法。因为Tomcat(源代码)在调用完有参数的init方法之后,就会默认调用其空参的方法。所有我们传递一个空参数的init方法(重写)之后,就相当于传递给了底层的有参方法。

1.3 注解开发取代web.xml(修改注解方式Servlet的模版)

在这里插入图片描述
WebServlet之后括号里,urlPatterns的赋值,就是客户端访问的虚拟路径。此时就不用配置web.xml了。
若即用注解又用web.xml文件,那将会产生冲突(虚拟路径一样的情况下)。若把虚拟路径改成不一样的,则使用两种方式都能访问到。此功能只有Java6及之后版本才支持。
切记修改模板之后,在新建servlet的对话框中,Name前面加“/”,左下角的勾选框要✔。

猜你喜欢

转载自blog.csdn.net/qq_45083975/article/details/92251200