利用反射机制 解析XMl(servlet原理)

本文介绍了一种利用反射机制解析XML配置文件并调用相应Servlet服务的方法。通过DOM4j解析XML,根据URL匹配到特定的servlet-name,再从servlet-name找到对应的servlet-class,最终使用反射实例化Servlet类并调用其方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用反射机制解析XMl

之前两篇文章我们学习了通过dom4j解析XML以及反射机制的简单应用
今天来看一个综合案例
今天看到一个面试题,通过反射机制,解析XML,实现servlet的服务
1.原理
当客户发起请求时,通过user.do去XML找到限定的类名,然后执行当中的方法。
没有用JavaWeb写,java项目道理都是一样的

整体思路

在这里插入图片描述
2.自定义一个接口 Servlet

package com.it.servlet;
public interface Servlet {
    //服务多次
    void  services();
}

3.定义一个实现类 UserServlet

package com.it.servlet;

public class UserServlet implements Servlet {
    @Override
    public void services() {
        System.out.println("--------------------user.do----------------------");
    }
}

4.XMl文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.it.servlet.UserServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/user.do</url-pattern>
  </servlet-mapping>
</web-app>

代码演示:

package com.it.XmlReflect;

import com.it.servlet.UserServlet;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.List;

//运用反射机制解析web.XML  调用servlet的方法
public class Foo {
    //获取XMl资源路径   user.dir用户的当前工作目录
    public static File XMLFile=new File(System.getProperty("user.dir") +"\\0911_reflect\\src\\web.xml");
    //读取XML  获得document
    public static Document getDocument(){
        SAXReader saxReader=new SAXReader();
        try {
            return  saxReader.read(XMLFile);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return  null;
    }

    //客户发起请求时 通过url(**.do)  比较 url-pattern   找到XML中的映射servlet-mapping
    // 通过url-pattern-->servlet-name-->servlet-->servlet-name-->servlet-class(包名.类名);
    public static String getServletName(String url){
        //获取document
        Document document=getDocument();
        //获取根
        Element root=document.getRootElement();
        //获取所有元素
        List<Element> elementList=root.elements("servlet-mapping");
        for(Element element:elementList) {
            if(element.element("url-pattern").getText().equals(url)){
                //获取servlet的name
              return   element.element("servlet-name").getText();
            }
        }
            return  null;
        }
//获取ClassName  servlet-class
    public static  String getServletClass(String ServletName){
        //获取document
        Document document=getDocument();
        //获取根
        Element root=document.getRootElement();
        List<Element> elementList=root.elements("servlet");
        for(Element element:elementList) {
            if(element.element("servlet-name").getText().equals(ServletName)){
                //获取servlet的name
                return   element.element("servlet-class").getText();
            }
        }
        return  null;
    }

    public static void main(String[] args) {
        String ServletClass=getServletClass(getServletName("/user.do"));
        //com.it.servlet.UserServlet
        try {
            //创建一个servlet类
            Class cls=Class.forName(ServletClass);
           // UserServlet userServlet=new UserServlet();
			//newInstance()返回object类型
            UserServlet userServlet=(UserServlet) cls.newInstance();
            //调用其中的方法  如dopost()  doget()...
            userServlet.services();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

在这里顺便了解了Class.forName的用法,以及它与new的区别,见下一篇文章,有详细介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值