【手写Tomcat】8.读取自定义的web.xml文件并进行初始化

        我们在上一篇文章中已经将我们自己的MyServlet写好了,但是当我们启动程序后,我们写的tomcat并不知道我们的MyServlet在哪里,我们就像tomcat那样通过web.xml的方式来进行配置。

        我们首先先来看一下我们的项目结构。

        我们建立了一个webapp目录,webapp里面我们就放静态资源,webapp下的WEB-INF下面放置我们的web.xml配置文件。我们在web.xml中编写自己的MyServlet映射关系。

        下面对上一篇文章中的2个Servlet进行配置,代码如下

<?xml version="1.0" encoding="utf-8" ?>

<myXml>
    <myServlet>
        <myServlet-name>cat</myServlet-name>
        <myServlet-class>com.clucky.myTomcat.myServlet.MyCatServlet</myServlet-class>
    </myServlet>
    <myServlet-mapping>
        <myServlet-name>cat</myServlet-name>
        <myUrl-pattern>/cat</myUrl-pattern>
    </myServlet-mapping>

    <myServlet>
        <myServlet-name>dog</myServlet-name>
        <myServlet-class>com.clucky.myTomcat.myServlet.MyDogServlet</myServlet-class>
    </myServlet>
    <myServlet-mapping>
        <myServlet-name>dog</myServlet-name>
        <myUrl-pattern>/dog</myUrl-pattern>
    </myServlet-mapping>
</myXml>

        这个xml中的元素名字都是我自定义的。下面我们来写一个类来对web.xml文件读取并进行初始化。


         我们建立了一个MyServletHandler类来对web.xml进行读取,并且将对应关系保存在map中。当然,这个map是public static的,其他类也可以访问,这就相对于一个配置类,在我们的程序启动时就会加载。

    //这个map用于存放名字和类的全路径的对应关系
    public static final ConcurrentHashMap<String, String> NAME_CLASS = new ConcurrentHashMap<>();
    //这个map用于存放对外访问路径和名字的关系
    public static final ConcurrentHashMap<String, String> PATTERN_NAME = new ConcurrentHashMap<>();
    //这个map用于存放对外访问路径和MyServlet的关系
    public static final ConcurrentHashMap<String, MyServlet> PATTERN_CLASS = new ConcurrentHashMap<>();

        然后我们创建一个init方法,里面就对web.xml文件进行读取,并将对应的映射关系存储起来。

    public static void init() {
        try {
            //得到项目根路径,并且对路径中的中文进行处理
            String path = URLDecoder.decode(Objects.requireNonNull(
                    MyServletHandler.class.getResource("/")).getPath(), "utf-8");
            得到解析器
            SAXReader saxReader = new SAXReader();
            //指定解析文件
            Document document = saxReader.read(new File(path + "/webapp/WEB-INF/web.xml"));
            //得到根节点
            Element rootElement = document.getRootElement();
            //分别得到我们在web.xml文件中的myServlets,myServletMappings元素。
            List<Element> myServlets = rootElement.elements("myServlet");
            List<Element> myServletMappings = rootElement.elements("myServlet-mapping");
            //将name,classPath的对应关系存如map中
            for (Element myServlet : myServlets) {
                String name = myServlet.element("myServlet-name").getText();
                String classPath = myServlet.element("myServlet-class").getText();
                NAME_CLASS.put(name,classPath);
            }
            //将pattern,name的对应关系存如map中
            for (Element myServletMapping : myServletMappings) {
                String name = myServletMapping.element("myServlet-name").getText();
                String pattern = myServletMapping.element("myUrl-pattern").getText();
                PATTERN_NAME.put(pattern,name);
            }
        } catch (Exception e) {
            System.out.println("初始化容器发生异常....");
        }
    }

         上面这段代码用到了java读取xml的技术,如果不清楚,请参考java解析xml,拿到xml中的数据后,我们将xml中编写的映射关系存储到map中进行管理。最后,给出完整代码

import com.clucky.myTomcat.myServlet.MyServlet;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.net.URLDecoder;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class MyServletHandler {

    //这个map用于存放名字和类的全路径的对应关系
    public static final ConcurrentHashMap<String, String> NAME_CLASS = new ConcurrentHashMap<>();
    //这个map用于存放对外访问路径和名字的关系
    public static final ConcurrentHashMap<String, String> PATTERN_NAME = new ConcurrentHashMap<>();
    //这个map用于存放对外访问路径和MyServlet的关系
    public static final ConcurrentHashMap<String, MyServlet> PATTERN_CLASS = new ConcurrentHashMap<>();

    public static void init() {
        try {
            //得到项目根路径,并且对路径中的中文进行处理
            String path = URLDecoder.decode(Objects.requireNonNull(
                    MyServletHandler.class.getResource("/")).getPath(), "utf-8");
            得到解析器
            SAXReader saxReader = new SAXReader();
            //指定解析文件
            Document document = saxReader.read(new File(path + "/webapp/WEB-INF/web.xml"));
            //得到根节点
            Element rootElement = document.getRootElement();
            //分别得到我们在web.xml文件中的myServlets,myServletMappings元素。
            List<Element> myServlets = rootElement.elements("myServlet");
            List<Element> myServletMappings = rootElement.elements("myServlet-mapping");
            //将name,classPath的对应关系存如map中
            for (Element myServlet : myServlets) {
                String name = myServlet.element("myServlet-name").getText();
                String classPath = myServlet.element("myServlet-class").getText();
                NAME_CLASS.put(name,classPath);
            }
            //将pattern,name的对应关系存如map中
            for (Element myServletMapping : myServletMappings) {
                String name = myServletMapping.element("myServlet-name").getText();
                String pattern = myServletMapping.element("myUrl-pattern").getText();
                PATTERN_NAME.put(pattern,name);
            }
        } catch (Exception e) {
            System.out.println("初始化容器发生异常....");
        }
    }

    @Test
    public void test(){
        init();
        System.out.println(NAME_CLASS);
        System.out.println(PATTERN_NAME);
    }
}

测试 

        我们编写一个测试方法进行测试

    @Test
    public void test(){
        init();
        System.out.println(NAME_CLASS);
        System.out.println(PATTERN_NAME);
    }

         运行,查看控制台输出,并和我们编写的web.xml进行比较

 控制台输出

 web.xml文件

        发现map中的对应关系和web.xml中一致,说明我们的代码没有问题。 


        现在,我们已经可以通过web.xml对我们自己编写的MyServlet进行配置了,在下一篇文章中,我们将通过web.xml中的配置来实现游览器对MyServlet的访问。 

猜你喜欢

转载自blog.csdn.net/m0_51545690/article/details/123283202
今日推荐