在上一篇博客 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)就可以通过反射创建不同的对象