178.XML反射webXML

it2023-01-23  50

在上一篇博客 XML解析webXML 的基础上,我们增加反射,通过url-pattern获取servlet-name然后通过servlet-name获取servlet-class,servlet-class就是类的路径,就可以反射创建对象实例

测试使用的web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>login</servlet-name> <servlet-class>com.server.basic.servlet.LoginSerlet</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.server.basic.servlet.RegisterSerxlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>reg</servlet-name> <url-pattern>/reg</url-pattern> </servlet-mapping> </web-app>
定义servlet接口继承之并创建LoginSerlet和RegisterSerxlet类
package com.server.basic.servlet; public interface servlet { public void service(); } package com.server.basic.servlet; public class LoginSerlet implements servlet{ public void service() { System.out.println("LoginSerlet"); } } package com.server.basic.servlet; public class RegisterSerxlet implements servlet{ public void service() { System.out.println("RegisterSerxlet"); } }
定义webContent类用于获取servlet-class,增加数据成员entitys和mappings将list转为map便于查找
import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class webContent { private List<Entity> entitys; private List<Mapping> mappings; //将list转为map便于查找 private Map<String, String> entitysMap = new HashMap<String, String>(); //key:servlet-name value:servlet-class private Map<String, String> mappingsMap = new HashMap<String, String>(); //key:url-pattern value:servlet-name public webContent(List<Entity> entitys, List<Mapping> mappings) { super(); this.entitys = entitys; this.mappings = mappings; for(Entity e:entitys) entitysMap.put(e.getNameString(), e.getClas()); for(Mapping m:mappings) { Set<String> set = m.getPatterns(); for(String patt:set) mappingsMap.put(patt, m.getName()); } } //通过url-pattern获取servlet-name然后通过servlet-name获取servlet-class,servlet-class就是类的路径,就可以反射创建对象实例 public String GetClas(String pattern) { return entitysMap.get(mappingsMap.get(pattern)); } }
Mapping类
import java.util.Set; import java.util.HashSet; /* * Mapping类用于存储以下xml解析的数据: * <servlet-mapping> * <servlet-name>login</servlet-name> * <url-pattern>/login</url-pattern> * <url-pattern>/g</url-pattern> * </servlet-mapping> * ... */ public class Mapping { private String name; private Set<String> patterns; //没有顺序不可重复 public Mapping() { patterns = new HashSet<String>(); } @Override public String toString() { String tmpString = "\n"; for(String s:patterns) tmpString+= s + "\n"; return "Mapping [name=" + name + ", patterns=" + tmpString + "]"; // return "Mapping [name=" + name + ", patterns=" + patterns + "]"; } public String getName() { return name; } public Set<String> getPatterns() { return patterns; } public void setName(String name) { this.name = name; } public void addPatterns(String pattern) { this.patterns.add(pattern); } }
Entity类
* * Entity类用于存储以下xml解析的数据: * <servlet> * <servlet-name>login</servlet-name> * <servlet-class>com.shsxt.LoginSerlet</servlet-class> * </servlet> * ... */ public class Entity { private String nameString; private String clas; public Entity() { } @Override public String toString() { return "Entity [nameString=" + nameString + ", clas=" + clas + "]"; } public String getNameString() { return nameString; } public String getClas() { return clas; } public void setNameString(String nameString) { this.nameString = nameString; } public void setClas(String clas) { this.clas = clas; } }
XMLWeb
package com.server.basic.servlet; import java.io.IOException; import java.lang.reflect.InvocationTargetException; 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; /* * SAX流程 */ public class XMLWeb { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { //SAX解析 //1.获取解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //2.从解析工厂获取解析器 SAXParser parse = factory.newSAXParser(); //3.加载文档Document注册处理器 WebHandler handler = new WebHandler(); //4.编写处理器 parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("com/server/basic/servlet/web.xml"), handler); //5.从注册处理器存储的容器传引用初始化webContent对象,内部提供获取类地址的共有方法GetClas webContent wc = new webContent(handler.getEntitys(), handler.getMappings()); //通过类地址动态创建对象 String classRoad = wc.GetClas("/login"); Class c = Class.forName(classRoad); servlet serv = (servlet)c.getConstructor().newInstance(); serv.service(); classRoad = wc.GetClas("/g"); c = Class.forName(classRoad); serv = (servlet)c.getConstructor().newInstance(); serv.service(); classRoad = wc.GetClas("/reg"); c = Class.forName(classRoad); serv = (servlet)c.getConstructor().newInstance(); serv.service(); } } //给注册处理器增加存储解析到的内容的容器 class WebHandler extends DefaultHandler{ //考虑到会存在多个person的情况下,用容器存储person private List<Entity> entitys = new ArrayList<>(); private List<Mapping> mappings = new ArrayList<>(); private Entity entity; private Mapping mapping; private String tag; //记录当前操作的标签名 private boolean isMapping = false; public List<Entity> getEntitys() { return entitys; } public List<Mapping> getMappings() { return mappings; } @Override public void characters(char[] ch, int start, int length) throws SAXException { String contents = new String(ch, start, length).trim(); //trim() 方法用于删除字符串的头尾空白符 if(null != tag) { if(isMapping) { if(tag.equals("servlet-name")) mapping.setName(contents); else if(tag.equals("url-pattern")) mapping.addPatterns(contents); }else { if(tag.equals("servlet-name")) entity.setNameString(contents); else if(tag.equals("servlet-class")) entity.setClas(contents); } } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(null != qName) { tag = qName; if(qName.equals("servlet")) { entity = new Entity(); isMapping = false; }else if(qName.equals("servlet-mapping")) { mapping = new Mapping(); isMapping = true; } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(null != qName) { if(qName.equals("servlet")) { entitys.add(entity); }else if(qName.equals("servlet-mapping")) { mappings.add(mapping); } } tag = null; } }

通过传入不同的字符串(url-pattern)就可以通过反射创建不同的对象

最新回复(0)