9.3 webxml解析及反射应用

    技术2022-08-01  72

    9.3 webxml解析及反射应用

    SAX方式解析webxml内容依据webxml数据进行反射事件处理数据目的过程代码结果

    SAX方式解析webxml内容

    数据

    <?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>login</servlet-name> <servlet-class>com.dxt.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> <url-pattern>/g</url-pattern> </servlet-mapping> <servlet> <servlet-name>reg</servlet-name> <servlet-class>com.dxt.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>reg</servlet-name> <url-pattern>/reg</url-pattern> </servlet-mapping> </web-app>

    代码       因为在xml数据中有 servlet 和 servlet-mapping 两个外部标签,所以我们要建立两个类来帮助解析xml数据,这两个类分别是Entity.class 和 Mapping.class。 Entity.class

    /** * 针对servlet建立的类 * @author dxt * */ public class Entity { private String name; private String clz; public Entity(){} public Entity(String name, String clz){ super(); this.name = name; this.clz = clz; } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public void setClz(String clz){ this.clz = clz; } public String getClz(){ return this.clz; } }

    Mapping.class

    import java.util.HashSet; import java.util.Set; /** * 针对<servlet-mapping> * @author dxt * */ public class Mapping { private String name; private Set<String> patterns; public Mapping(){ patterns = new HashSet<String>(); } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public Set<String> getPatterns(){ return this.patterns; } public void addPattern(String pattern){ this.patterns.add(pattern); } }

    SAX解析代码:

    import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XmlTest03 { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{ //1. 获取解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //2. 从解析工厂获取解析器 SAXParser parse = factory.newSAXParser(); //3. 编写处理器 //4. 加载文档注册处理器 WebHandler handler = new WebHandler(); //5. 进行解析 parse.parse(Thread.currentThread().getContextClassLoader() .getResourceAsStream("dxt/webxml/servlet.xml"), handler); //处理数据 List<Entity> entitys = handler.getEntitys(); List<Mapping> mappings = handler.getMappings(); for(Entity e : entitys){ System.out.println(e.getName() + "---" + e.getClz()); } for(Mapping m : mappings){ System.out.println(m.getName() + "----" + m.getPatterns()); } } } class WebHandler extends DefaultHandler{ private List<Entity> entitys; private List<Mapping> mappings; private Entity entity; private Mapping mapping; private String tag; //存储操作标签 private boolean isMapping = false; public void startDocument(){ System.out.println("------文档解析开始------"); entitys = new ArrayList<Entity>(); mappings = new ArrayList<Mapping>(); } public void startElement(String uri, String localName, String qName, Attributes attributes){ if(null != qName){ //处理换行与空格 tag = qName; //处理对应的标签 if(tag.equals("servlet")){ entity = new Entity(); isMapping = false; }else if(tag.equals("servlet-mapping")){ mapping = new Mapping(); isMapping = true; } } } public void characters(char[] ch, int start, int length){ String contents = new String(ch, start, length).trim(); if(null != tag){ if(isMapping){ //处理 mapping if(tag.equals("servlet-name")){ mapping.setName(contents); }else if(tag.equals("url-pattern")){ mapping.addPattern(contents); } }else{ //处理entity if(tag.equals("servlet-name")){ entity.setName(contents); }else if(tag.equals("servlet-class")){ entity.setClz(contents); } } } } public void endElement(String uri, String localName, String qName){ if(null != qName){ if(qName.equals("servlet")){ entitys.add(entity); }else if(qName.equals("servlet-mapping")){ mappings.add(mapping); } } tag = null; } public void endDocument(){ System.out.println("------文档解析结束------"); } public List<Entity> getEntitys(){ return this.entitys; } public List<Mapping> getMappings(){ return this.mappings; } }

    结果

    依据webxml数据进行反射事件处理

    数据

    <?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>login</servlet-name> <servlet-class>dxt.webxml.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> <url-pattern>/g</url-pattern> </servlet-mapping> <servlet> <servlet-name>reg</servlet-name> <servlet-class>dxt.webxml.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>reg</servlet-name> <url-pattern>/reg</url-pattern> </servlet-mapping> </web-app>

          在数据中每一个 url-pattern 都是唯一的,可由url-pattern 找到对应的 servlet-name,再由 servlet-name 找到对应的 servlet-class。每一个 url-pattern 都唯一对应一个 servlet-class,每个 servlet-class 可对应多个 url-pattern。servlet-class标签中的内容就是项目中对应类的地址,可由此地址找到对应类。

    目的

          依据xml文件,通过我们输入的 url-pattern 找到项目中的对应类,然后使用此类创建对象。

    过程

    解析xml文件。只解析,并不需要打印结果。需要使用Entity.class 和 Mapping.class两个类,这两个类在前面已给出。通过给定的 url-pattern 找到对应的 servlet-class。在WebContext.java中实现。在项目中创建 servlet-class 对应的类。在xmlTest03中使用WebContext提供的类名,通过反射找到对应的类,并创建对象。

    代码

    XmlTest03.java:

    import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XmlTest03 { public static void main(String[] args) throws Exception{ //1. 获取解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //2. 从解析工厂获取解析器 SAXParser parse = factory.newSAXParser(); //3. 编写处理器 //4. 加载文档注册处理器 WebHandler handler = new WebHandler(); //5. 进行解析 parse.parse(Thread.currentThread().getContextClassLoader() .getResourceAsStream("dxt/webxml/servlet.xml"), handler); //反射事件 //1. 创建上下文对象 WebContext wc = new WebContext(handler.getEntitys(), handler.getMappings()); //2. 依据WebContext 获取我们想要得到的 对应的类名 //2.1 假设我们输入的是“/reg” String name = wc.getClz("/reg"); //3. 有了类名 ---> 使用反射 获取对应类的信息, 类名就是xml数据中的<servlet-class> Class clz = Class.forName(name); //4. 使用反射进行实例化 Servlet s = (Servlet)clz.getConstructor(null).newInstance(null); s.service(); //调用对应的方法 } } class WebHandler extends DefaultHandler{ private List<Entity> entitys; private List<Mapping> mappings; private Entity entity; private Mapping mapping; private String tag; //存储操作标签 private boolean isMapping = false; public void startDocument(){ System.out.println("------文档解析开始------"); entitys = new ArrayList<Entity>(); mappings = new ArrayList<Mapping>(); } public void startElement(String uri, String localName, String qName, Attributes attributes){ if(null != qName){ //处理换行与空格 tag = qName; //处理对应的标签 if(tag.equals("servlet")){ entity = new Entity(); isMapping = false; }else if(tag.equals("servlet-mapping")){ mapping = new Mapping(); isMapping = true; } } } public void characters(char[] ch, int start, int length){ String contents = new String(ch, start, length).trim(); if(null != tag){ if(isMapping){ //处理 mapping if(tag.equals("servlet-name")){ mapping.setName(contents); }else if(tag.equals("url-pattern")){ mapping.addPattern(contents); } }else{ //处理entity if(tag.equals("servlet-name")){ entity.setName(contents); }else if(tag.equals("servlet-class")){ entity.setClz(contents); } } } } public void endElement(String uri, String localName, String qName){ if(null != qName){ if(qName.equals("servlet")){ entitys.add(entity); }else if(qName.equals("servlet-mapping")){ mappings.add(mapping); } } tag = null; } public void endDocument(){ System.out.println("------文档解析结束------"); } public List<Entity> getEntitys(){ return this.entitys; } public List<Mapping> getMappings(){ return this.mappings; } }

    WebContext.java:

    import java.util.HashMap; import java.util.List; import java.util.Map; /** * 目的: 根据url-pattern 找 servlet-class * 对于webxml数据 * 可以依据<servlet-mapping> 中的pattern 找到 name * 在根据 name 在<servlet> 中找到class * @author dxt * */ public class WebContext { private List<Entity> entitys; private List<Mapping> mappings; //创建两个map数据,帮助解决问题 //key:servlet-name value:servlet-class private Map<String, String> entityMap = new HashMap<String, String>(); //key:url-pattern value:servlet-name private Map<String, String> mappingMap = new HashMap<String, String>(); public WebContext(List<Entity> entitys, List<Mapping> mappings){ this.entitys = entitys; this.mappings = mappings; //将entity的List转成了map for(Entity entity : entitys){ entityMap.put(entity.getName(), entity.getClz()); } //将mapping的List转为map for(Mapping mapping : mappings){ for(String pattern : mapping.getPatterns()){ mappingMap.put(pattern, mapping.getName()); } } } /** * 依据url-pattern 找对应的 servlet-class * 一个url-pattern唯一对应一个class * 一个class可对应多个url-pattern * 返回servlet-class * @param pattern * @return */ public String getClz(String pattern){ String name = mappingMap.get(pattern); //找到对应name return entityMap.get(name); //找到对应class } }

    Servlet.java:

    /** * Servlet接口 * 用于测试 * @author dxt * */ public interface Servlet { void service(); }

    LoginServlet.java

    /** * 实现Servlet接口 * @author dxt * */ public class LoginServlet implements Servlet { public void service() { System.out.println("LoginServlet"); } }

    RegisterServlet.java:

    /** * 实现Servlet接口 * @author dxt * */ public class RegisterServlet implements Servlet { public void service() { System.out.println("RegisterServlet"); } }

    结果

    Processed: 0.017, SQL: 9