包含了:反射,容器,sax解析xml知识点
结构图:
首先class xml:
public class XML {
public static void main(String[] args) throws Exception {
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser Parse=factory.newSAXParser();
Handler handler=new Handler();
Parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("cn/xjh3/Net/WebServer/servlet/web.xml"),handler);
Webcontext context=new Webcontext(handler.getEntitys(),handler.getMappings());//调用上下文类 处理Handler得到的数据
String classname= context.getclz("/g");//输入url-pattern
Class clz=Class.forName(classname);
Servlet a=(Servlet) clz.getConstructor().newInstance();
a.service();
}
}
class Handler extends DefaultHandler {//继承DefaultHandler类,必要条件,处理类
private List<Entity> Entitys=new ArrayList<>();//定义Entity和Mapping对象容器,装载解析的数据
private List<Mapping> Mappings=new ArrayList<>();
private Mapping mapping;
private Entity entity;
private String tag;
private boolean ismapping=false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {//解析一个<></>内容块开始
System.out.println(qName+"---->解析开始");
tag=qName;//设立一个标志位,在解析内容时候用于判断
if(qName=="servlet"){
entity=new Entity();
}else if(qName=="servlet-mapping"){
mapping=new Mapping();
ismapping=true;//读取servlet-mapping的标志
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {//解析一个内容块结束
System.out.println(qName+"---->解析结束");
if(qName.equals("servlet")){Entitys.add(entity);}//把类加入容器内
if(qName.equals("servlet-mapping")){Mappings.add(mapping);}
tag=null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(tag!=null){//处理了,解析完一个内容快后有空内容的情况
String contents=new String(ch,start,length).trim();//trim去掉空
if(ismapping){//操作servlet-mapping
if(tag=="servlet-name"){mapping.setName(contents);}
else if(tag=="url-pattern"){mapping.addPatterns(contents);}
}else {//操作servlet
if(tag=="servlet-name"){entity.setName(contents);}
else if(tag=="servlet-class"){entity.setClz(contents);}
}
}}
public List<Entity> getEntitys() {
return Entitys;
}
public void setEntitys(List<Entity> entitys) {
Entitys = entitys;
}
public List<Mapping> getMappings() {
return Mappings;
}
public void setMappings(List<Mapping> mappings) {
Mappings = mappings;
}
}
两个类来存放xml解析的数据:
Entity类用来存 内的内容:
public class Entity {
private String name;//两个标签块
private String clz;
public Entity() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClz() {
return clz;
}
public void setClz(String clz) {
this.clz = clz;
}
}
Mapping类来存储 的内容:
public class Mapping {
private String name;//两个标签块
private Set<String > patterns;
public Mapping(){
patterns=new HashSet<String>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getPatterns() {
return patterns;
}
public void setPatterns(Set<String> patterns) {
this.patterns = patterns;
}
public void addPatterns(String pattern){
this.patterns.add(pattern);//便于操作
}
}
接下来是在XML内调用的上下文类:
处理XML类内解析的数据
public class Webcontext {//上下文类
private List<Entity> E=null;
private List<Mapping> M=null;
private Map<String,String> EntityMap=new HashMap<>();//KEY->Entity里的name,VALUE->Entity里的class
private Map<String,String> MappingMap=new HashMap<>();//KEY->Mapping里的pattern,VALUE->Mapping里的name
public Webcontext(List<Entity> E, List<Mapping> M) {
this.E = E;
this.M = M;
for(Entity e:E){
EntityMap.put(e.getName(),e.getClz());//将Handler得到的entity list转换为map
}
for(Mapping m:M){
for(String pattern:m.getPatterns()){
MappingMap.put(pattern,m.getName());//将得到的mapping list转换为map,因为mapping内还有一个set容器,双重循环
}
}
}
//通过URL路径找到class:由url-pattern找到servlet-name再找到servlet-class
public String getclz(String pattern){//得到类名
String name=MappingMap.get(pattern);
return EntityMap.get(name);
}
}
新建一个Servlet接口
public interface Servlet {
void service();
}
两个继承该接口的类:在xml文件内的类名,用于被反射
public class LoginServlet implements Servlet{
@Override
public void service() {
System.out.println("登录");
}
}
public class RegisterServlet implements Servlet{
@Override
public void service() {
System.out.println("注册");
}
}
最后附上被解析web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>cn.xjh3.Net.WebServer.servlet.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>reg</servlet-name>
<servlet-class>cn.xjh3.Net.WebServer.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>