解析Webxml文件 反射

本文介绍了如何解析Web.xml文件,重点关注servlet和servlet-mapping部分。通过创建Servlet和Mapping类,将解析后的数据封装并存储。解析过程中,Mapping类使用特定的add方法管理url-pattern。解析完成后,利用Map数据结构建立servlet-name到servlet-class以及url-pattern到servlet-name的映射。最终,通过WebContext处理这些数据,实现URL到类的映射,创建接口并让RegisterServlet和LoginServlet实现该接口,输出类名。
摘要由CSDN通过智能技术生成

分析xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>servlet.LoginServlet</servlet-class>
    </servlet>

    <servlet>
    <servlet-name>reg</servlet-name>
    <servlet-class>servlet.RegisterServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
        <url-pattern>/g</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>reg</servlet-name>
        <url-pattern>/reg</url-pattern>
    </servlet-mapping>
</web-app>

可以看到有servlet 和 servlet-mapping两个部分
servlet
1.servlet-name
2.servlet-class

servlet-mapping
1.servlet-name
2.url-pattern 有多个,所以在解析时应该用容器存储

按照xml内容,建立Servlet类和Mapping类,进行封装
特殊地,Mapping类不使用set方法存储pattern,而是写一个add方法将pattern放进容器当中。

public void addPattern(String pattern){
            this.patterns.add(pattern);

    }

主要的解析部分
固定套路来一波

SAXParserFactory factory=SAXParserFactory.newInstance();
        SAXParser parser=factory.newSAXParser();
        WebHandler webHandler=new WebHandler();
        parser.parse(Thread.currentThread().getContextClassLoader().
                getResourceAsStream("servlet/web.xml"),webHandler);

解析

class WebHandler extends DefaultHandler {
    private List<Servlet> servlets=null;
    private List<Mapping>mappings=null;
    private boolean isServlet;
    private String tag;
    Mapping mapping=null;
    Servlet servlet=null;
    @Override
    public void startDocument() throws SAXException {
        servlets=new ArrayList<>();
        mappings=new ArrayList<>();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

        if(qName.equals("servlet")){
             servlet=new Servlet();
            isServlet=true;
        } else if (qName.equals("servlet-mapping")){
            mapping=new Mapping();
            isServlet=false;
        }
        tag=qName;

    }


    @Override
    public void characters(char[] ch, int start, int length) throws NullPointerException {
        String contents=new String(ch,start,length).trim();
        if(tag!=null) {
            if (isServlet) {
                if (tag.equals("servlet-name")) {
                    servlet.setName(contents);
                } else if (tag.equals("servlet-class")) {
                    servlet.setClz(contents);
                }

            } else {
                if (tag.equals("servlet-name")) {
                    mapping.setName(contents);
                } else if (tag.equals("url-pattern")) {
                    mapping.addPattern(contents);
                }

            }
        }


    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {

        if(qName.equals("servlet")){
            servlets.add(servlet);
        }else if(qName.equals("servlet-mapping")){
            mappings.add(mapping);
        }
        tag=null;
    }



    public List<Mapping> getMappings() {
        return mappings;
    }

    public List<Servlet> getServlets() {
        return servlets;
    }
}

接收(固定套路下面)

List<Servlet> servlets=webHandler.getServlets();
List<Mapping>mappings=webHandler.getMappings();

以上步骤就已经将xml文件当中的数据提取到两个容器当中,弄个输出跑一下

        for (Servlet servlet:servlets
             ) {
            System.out.println(servlet.getName()+"-->"+servlet.getClz());
        }

        for (Mapping mapping:mappings
             ) {
            for (String pattern:mapping.getPatterns()
                 ) {
                System.out.println(mapping.getName()+"-->"+pattern);
            }
        }

在这里插入图片描述

然后这个xml解析有什么特殊之处呢?解析的目的何在?

在地址后面加上/g或者是/login就可以找到login,加上/reg就可以找到reg,
然后reg或者login又可以找到他们对应的class,得到class就可以进行映射,剖析类。
总的来说就是通过url找到类进行映射。

写一个WebContext对两个容器进行数据处理,将两个容器传过去

WebContext context=new WebContext(servlets,mappings);

既然是对应寻找,就要用到Map
servlet
1.servlet-name
2.servlet-class
key servlet-name value servlet-class

servlet-mapping
1.servlet-name
2.url-pattern 有多个,所以在解析时应该用容器存储
key url-pattern value servlet-name

url找name,通过name找到class
处理数据的类是这样的

public class WebContext {
    private List<Servlet> servlets;
    private List<Mapping> mappings;
    private Map<String ,String > servletMap=new HashMap<>();
    private Map<String ,String >mappingMap=new HashMap<>();

    public WebContext(List<Servlet> servlets, List<Mapping> mappings) {
        this.servlets = servlets;
        this.mappings = mappings;
        for (Servlet servlet:servlets
             ) {
            servletMap.put(servlet.getName(),servlet.getClz());
        }
        for (Mapping mapping:mappings
             ) {
            for (String pattern:mapping.getPatterns()
                 ) {
                mappingMap.put(pattern,mapping.getName());
            }
        }


    }
    //这样通过传入url就返回了class
    public String getClz(String url){
        String name=mappingMap.get(url);
        return servletMap.get(name);
    }

    public WebContext() {
    }
}

现在解析的方法已经写出来了,xml文件里面有两个类的地址
(servlet是包名)
servlet.RegisterServlet servlet.LoginServlet
那就实现这两个类,写一个接口,让这两个类继承service方法,
分别输出他们的类名

使用

WebContext context=new WebContext(servlets,mappings);
        String className=context.getClz("/g");
        Class clz3=Class.forName(className);
        LoginServlet loginServlet= (LoginServlet) clz3.getConstructor().newInstance();
        loginServlet.service();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值