JAVA之Servlet详解

2022-07-27,,

Servlet的详解2

1.ServletConfig接口介绍

ServletConfig接口,从名字上来看,就知道是Servlet程序的配置信息接口

我们进入源码看一下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.servlet;

import java.util.Enumeration;

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

由以上代码我们可以知道,ServletConfig接口有3个作用:

  • 获取Servlet的上下文对象
  • 获取Servlet程序的别名servlet-name
  • 获取初始化参数init-param

在Servlet接口里,init方法的其中一个参数就是ServletConfig对象,所以我们在初始化的时候可以获取Servlet类的一些初始化信息,代码如下:

 /**
     * 当第一次访问该资源时,创建Servlet程序会调用此方法,且只会执行一次,和构造器一样
     * @param servletConfig
     * @throws ServletException
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        //获取参数值
        String username = servletConfig.getInitParameter("username");
        //获取上下文对象
        ServletContext servletContext = servletConfig.getServletContext();
        //获取Servlet的别名
        String servletName = servletConfig.getServletName();
        System.out.println(username);
        System.out.println("初始化了一次");
    }

有一点需要注意的是,在ServletConfig的获取初始化参数的方法中,这里的参数是需要自己去设置的,如果没有设置,这里的值是为null的,代码如下:
这是一个完整的Servlet类的配置信息

    <!--servlet标签给tomcat配置servlet程序-->
    <servlet>
        <!--servlet-name标签给Servlet程序起一个别名,一般是类名-->
        <servlet-name>MyFirstServlet</servlet-name>
        <!--Servlet-class表情是Servlet程序的全类名-->
        <servlet-class>com.hsf.servlet.MyFirstServlet</servlet-class>

        <!--init-param是初始化参数-->
        <init-param>
            <!--参数名-->
            <param-name>username</param-name>
            <!--参数值-->
            <param-value>jdbc:mysql://localhost:3306/jmy?useSSL=false</param-value>
        </init-param>
    </servlet>

    <!--servlet-mapping表情给Servlet程序配置访问地址-->
    <servlet-mapping>
        <!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
        <servlet-name>MyFirstServlet</servlet-name>
        <!--url-pattern标签配置访问地址
            /      :斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
            /hello :斜杠hello表示地址为:http://ip:port/工程路径/hello
        -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

如上面, 是用来设置初始化参数的,他是以类似键值对的形式设置的,我们可以通过【参数名】找到对应的 参数值,一般情况下,我们可以将一些需要用到的信息写在里面,需要用的时候调用即可!


2、ServletContext接口介绍

2.1、什么ServletContext

  • ServletContext是一个接口,它表示上下文对象
  • 一个web工程,只有一个ServletContext对象实例
  • ServletContext对象是一个域对象,所谓域对象,就是可以向map一样存取操作数据,这里的域指的是可以存取数据的范围,说白了,域对象就是可以在一定区域内存取数据的对象。

下面我们比较下ServletContext对象和map存取数据的方法
---------------------------存数据------------取数据---------------删除数据
--------------map------- put()--------------get()------------------remove()
ServletContext------setAttrbute()-----getAttrbute()-----removeAttrbute()

2.2、ServletContext接口的四个作用

  • 获取当前的工程路径
  • 获取工程部署后在服务器硬盘上的绝对路径
  • 像map一样存储数据
  • 获取web.xml中配置的上下文参数context-param

ServletContext域对象的特点

Context对象是在web程序启动的时候随之启动的,当web工程停止的时候Context对象也会随之销毁,一个web工程只有一个Context域对象,为所有的Servlet类共享,比如,我们设置一个上下文对象的参数:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--context对象的参数-->
    <context-param>
        <!--参数名-->
        <param-name>name</param-name>
        <!--参数值-->
        <param-value>context</param-value>
    </context-param>


    <servlet>
        <servlet-name>MyFirstServlet</servlet-name>
        <servlet-class>com.hsf.servlet.MyFirstServlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>jdbc:mysql://localhost:3306/jmy?useSSL=false</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyFirstServlet</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>

在上面的代码中,我们设置了一个context-param–>context参数,注意:一个context-param标签里只能存放一组键值对,,然后,我们回到我们的Servlet类去进行一个访问操作,

这样,就能获取到设置的值了,Servlet同样可以设置初始化参数,之前的博客里有提到,Servlet里有个init-param,同样也是由来设置参数的,他们的区别在于,一个类似于全局变量,是所有的Servlet类都可以访问到的,一个类似于局部变量,只有当前的Servlet类可以使用,也就是只能自己使用。

ServletContext存取数据

当然,除了在xml文件里设置参数,我们也可以通过方法在Servlet类里去存入数据,我们先写一个样例代码:

package com.hsf.servlet;

import javax.servlet.*;
import java.io.IOException;


public class ServletDemo4 implements Servlet {

    public void init(ServletConfig servletConfig) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext servletContext = getServletConfig().getServletContext();
        //存入数据
        servletContext.setAttribute("name","金木研");
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

在上面的代码里,我选择了实现Servlet接口去实现一个Servlet类,在service方法中,调用了getServletConfig方法获取了ServletConfig对象,Servlet接口本身是没有获取ServletContext对象的方法的,但是没关系,Servlet接口有获取ServletConfig对象的方法,而ServletConfig有获取ServletContext对象的方法,所以我们可以通过Servlet间接获取到ServletContext对象,然后,我们使用setAttribute方法去存入一组键值对,当我们需要使用的时候就可以直接通过键去获取对应的值了,在前面ServletContext对象的特点里我们有提到,Context对象是所有的Servlet对象所共有的,且Context域对象是随着web工程的关闭而关闭,也就是说,在web工程还没关闭的时候,所有的Servlet类都可以去访问到存入的这个值,下面我们来测试一下:

package com.hsf.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name =(String) getServletContext().getAttribute("name");
        System.out.println(name);
    }
}

在上面的代码中,我们在另一个Servlet类中取出了之前存入的name值,我们启动tomcat,运行如下:

可以看到,金木研被取出了(上面其他的打印是之前测试时的,不用在意),由此,我们可以得出,所有的Servlet类共享一个上下文的对象(ServlertContext),并且ServletContext对象随工程的启动而启动

IDEA部署工程的原理

我们先来看一段代码

package com.hsf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*通过继承Servlet接口的实现类HttpServlet类来实现Servlet*/
public class ServletDemo2 extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("aaa");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("fufu真帅");
        //获取上下文对象
        ServletContext servletContext = this.getServletConfig().getServletContext();
        System.out.println("上下文对象--->"+servletContext);
        //获取上下文初始化参数
        String name = servletContext.getInitParameter("name");
        System.out.println("上下文初始化参数--->"+name);
        //获取当前的工程路径
        String contextPath = servletContext.getContextPath();
        System.out.println("前的工程路径--->"+contextPath);
        //获取工程部署后在服务器硬盘上的绝对路径
        String realPath = servletContext.getRealPath("/");
        System.out.println("程部署后在服务器硬盘上的绝对路径--->"+realPath);
    }
}

运行如下:

在上面,我们获取了工程路径:/Maven_01,和部署之后,工程在硬盘上的绝对路径:
**C:\Users\asus\IdeaProjects\HTML\out\artifacts\Maven_01_JavaWeb_war_exploded**,这个地址对应的是工程启动时IDEA复制的web文件副本的地址,我们打开文件管理器查看

与IDEA里的web进行对比

我们发现它们是一模一样的,这时,我们在打开IDEA里的web路径

(以下是展示的路径)
IDEA里的web目录的路径:
C:\Users\asus\IdeaProjects\HTML\Maven_01
IDEA启动时部署的工程目录下的web目录的副本路径:
C:\Users\asus\IdeaProjects\HTML\out\artifacts\Maven_01_JavaWeb_war_exploded

**Tomcat部署工程的原理:**当我们启动tomcat时,会有如下信息

那么,这个路径是用来干嘛的呢,我们去看一下,

在之前的一篇介绍Tomcat的博客里,我有介绍过tomcat部署web项目的几种方式,其中一种是在conf-catalina-localhost文件夹下创建一个web工程的xml文件,使用方式去映射一个web文件,在IDEA中部署项目就是这个原理,在Tomcat启动时,会自动生成一个该项目的副本文件,同时会产生一个该项目的xml配置文件,在配置文件中

<Context path="/Maven_01" docBase="C:\Users\asus\IdeaProjects\HTML\out\artifacts\Maven_01_JavaWeb_war_exploded" />

将当前的工程路径设置成了**/Maven_01**,同时映射到启动时生成的web副本文件,所以,在前面我们获取的当前的工程路径为**/Maven_01**,部署后的工程在服务器硬盘上的绝对路径为:C:\Users\asus\IdeaProjects\HTML\out\artifacts\Maven_01_JavaWeb_war_exploded

以上就是今天的内容了!

2020-11-28 又是努力的一天,加油吧!代码人

本文地址:https://blog.csdn.net/qq_47953855/article/details/110264217

《JAVA之Servlet详解.doc》

下载本文的Word格式文档,以方便收藏与打印。