欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA之Servlet详解

程序员文章站 2022-04-01 20:49:29
Servlet的详解21.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 i...

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类去进行一个访问操作,
JAVA之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,运行如下:
JAVA之Servlet详解
可以看到,金木研被取出了(上面其他的打印是之前测试时的,不用在意),由此,我们可以得出,所有的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);
    }
}

运行如下:
JAVA之Servlet详解
在上面,我们获取了工程路径:/Maven_01,和部署之后,工程在硬盘上的绝对路径:
**C:\Users\asus\IdeaProjects\HTML\out\artifacts\Maven_01_JavaWeb_war_exploded**,这个地址对应的是工程启动时IDEA复制的web文件副本的地址,我们打开文件管理器查看
JAVA之Servlet详解
与IDEA里的web进行对比
JAVA之Servlet详解
我们发现它们是一模一样的,这时,我们在打开IDEA里的web路径
JAVA之Servlet详解
(以下是展示的路径)
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时,会有如下信息
JAVA之Servlet详解
那么,这个路径是用来干嘛的呢,我们去看一下,
JAVA之Servlet详解
在之前的一篇介绍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