XML-建模

XML-建模

建模的由来

  • 就是将指定的xml字符串当作对象来操作
    如果说当对一个指定的xml格式字符串完成了建模操作,
    好处在于,只需要调用指定的方法就可以完成预定的字符串获取;

建模的思路

好处:提高代码的复用性

  1. 分析需要被建模的文件中有那几个对象
  2. 每个对象拥有的行为以及属性
  3. 定义对象从小到大(从里到外)
  4. 通过23种的设计模式中的工厂模式,解析xml生产出指定对象

建模分两步:

  1. 以面向对象的编程思想,描述xml资源文件
  2. 将xml文件中内容封装进model实体对象。

代码:

按照以下代码得到值,会出现代码资源浪费,代码繁琐。
在这里插入图片描述

一个小案例来解决以上问题

对mvc.xml建模
1.获取第二个action中的type的值
2.获取第二个action的第二个forward的path

mvc.xml 文本内容

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<!-- action标签:可以饱含0~N个forward标签 path:/开头的字符串,并且值必须唯一 非空 type:字符串,非空 -->
	<action path="/regAction" type="test.RegAction">
		<!-- forward标签:没有子标签; name:字符串,同一action标签下的forward标签name值不能相同 ; path:/开头的字符串 
			redirect:只能是false|true,允许空,默认值为false -->
		<forward name="failed" path="/reg.jsp" redirect="false" />
		<forward name="success" path="/login.jsp" redirect="true" />
	</action>

	<action path="/loginAction" type="test.LoginAction">
		<forward name="failed" path="/login.jsp" redirect="false" />
		<forward name="success" path="/main.jsp" redirect="true" />
	</action>
</config>

分析:mvc.xml
每一个标签对应一个实体类,标签中的属性对应实体类中的属性;
ConfigModel
查找
新增
ActionModel
属性
新增
查询
ForwardModel
属性

ForwardModel 实体类

package com.hyf.model;

import java.util.Map;

public class ForwardModel {
//	 <forward name="success" path="/main.jsp" redirect="true" />
	private  String sname;
	private  String path;
	private  boolean redirect =true;
	
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public boolean isRedirect() {
		return redirect;
	}
	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}
	
}

ActionModel 实体类

package com.hyf.model;

import java.util.HashMap;
import java.util.Map;

public class ActionModel {
//	<action path="/loginAction" type="test.LoginAction">
	private  String path;
	private  String type;
	private  Map<String , ForwardModel> fmap=new HashMap<>();
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	
	/**
	 * 压栈
	 * @param forwardModel
	 */
	public  void push(ForwardModel forwardModel) {
       fmap.put(forwardModel.getSname(), forwardModel);	
	}
	
	/**
	 * 弹栈
	 * @param name
	 * @return
	 */
	public ForwardModel pop(String name){
		return  fmap.get(name);   // map 集合通过key值来获取value 值
	}
}

ConfigModel 实体类

package com.hyf.model;

import java.util.HashMap;
import java.util.Map;

public class ConfigModel {
     private Map<String , ActionModel> aMap=new HashMap<>();
     
     /**
      * 堆栈
      * @param actionModel
      */
    public void push(ActionModel actionModel) {
    	 aMap.put(actionModel.getPath(),actionModel);
     }
    
    /**
     * 弹栈
     * @param path
     * @return 
     */
    public ActionModel pop(String path) {
    	return  aMap.get(path);
    }
}

工厂设计模式

why:能够提高代码的复用性
how:只要建立一个方法,去生产指定的需要的对象
where:去生产指定的你需要的对象,以便重复使用

你要得到什么就在工厂定义方法
ConfigModelFactory 工厂

package com.hyf.model;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ConfigModelFactory {

	/**
	 * 默认资源文件mvc.xml是放在建模类的同包下
	 * 
	 * @return
	 * @throws Exception 
	 */
	public static ConfigModel build() throws Exception {
		return build("mvc.xml");
	}

	/**
	 * 当资源文件,需要手动改变位置的情况下,那么需要调用以下方法
	 * 
	 * @param xmlPath
	 * @return
	 * @throws Exception 
	 */
	public static ConfigModel build(String xmlPath) throws Exception {
		ConfigModel configModel = new ConfigModel();
		ActionModel actionModel=null;
		ForwardModel forwardModel=null;

		InputStream is = ConfigModelFactory.class.getResourceAsStream(xmlPath);
		SAXReader reader=new SAXReader();
		Document doc=reader.read(is);
		List<Element> actionEles=doc.selectNodes("config/action");
        for (Element actionEle : actionEles) {
        	actionModel=new ActionModel();
//        	填充actionModel
        	actionModel.setPath(actionEle.attributeValue("path"));// 添加属性值
        	actionModel.setType(actionEle.attributeValue("type"));
            List<Element> forwardEles=actionEle.selectNodes("forward");
            for (Element forwardEle : forwardEles) {
            	forwardModel=new ForwardModel();
            	forwardModel.setSname(forwardEle.attributeValue("name"));
            	forwardModel.setPath(forwardEle.attributeValue("path"));
            	forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));
            	actionModel.push(forwardModel);
			}
            configModel.push(actionModel);
		}
		return configModel;
	}
}

测试:

package com.hyf.model;

public class Test {
	public static void main(String[] args) throws Exception {
		ConfigModel configModel = ConfigModelFactory.build();
//		1.获取第二个action中的type的值
		ActionModel  actionModel  = configModel.pop("/loginAction");
		System.out.println("第二个action中的type的值      "+actionModel.getType());
//		2.获取第二个action的第二个forward的path
		ForwardModel forwardModel = actionModel.pop("success");
		System.out.println("第二个action的第二个forward的path  "+forwardModel.getPath());
	}
}

输出:
在这里插入图片描述

  • 温馨提示:想要什么方法自己就在工厂(ConfigModelFactory 类)中定义;

案例2:建模加强版:

  • 1、对web.xml进行建模
  • 2、通过url-pattern读取到servlet-class的值

web.xml 文本内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <servlet>
  	<servlet-name>jrebelServlet</servlet-name>
  	<servlet-class>com.hyf.xml.JrebelServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>jrebelServlet</servlet-name>
  	<url-pattern>/jrebelServlet</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>jrebelServlet2</servlet-name>
  	<servlet-class>com.hyf.xml.JrebelServlet2</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>jrebelServlet2</servlet-name>
  	<url-pattern>/jrebelServlet2</url-pattern>
  	<url-pattern>/jrebelServlet3</url-pattern>
  </servlet-mapping>
</web-app>

分析 web.xml 得到实体类,(标签文本内容就是实体类的属性)

ServletNameModel 类

package com.hyf.model.work;

public class ServletNameModel {
    private String value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

UrlPatternModel 类

package com.hyf.model.work;

public class UrlPatternModel {
    private  String  value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

ServletMappingModel 类

package com.hyf.model.work;

import java.util.HashSet;
import java.util.Set;


public class ServletMappingModel {
	/**
	 * 名字
	 */
	private ServletNameModel servletNameModel;
	private Set<UrlPatternModel> s=new HashSet<>();   // 在 web.xml 中出现多个,而且不能出现重复所以要用 set 集合
	
	public ServletNameModel getServletNameModel() {
		return servletNameModel;
	}
	public void setServletNameModel(ServletNameModel servletNameModel) {
		this.servletNameModel = servletNameModel;
	}
	
	public void  push(UrlPatternModel upm) {
		s.add(upm);
	}
	
	public Set<UrlPatternModel> pop(){
		return s;
	}
	
	
}

ServletClassModel 类

package com.hyf.model.work;

public class ServletClassModel {
    private  String value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

ServletModel 类

package com.hyf.model.work;

public class ServletModel {
    private   ServletNameModel servletNameModel;
    private   ServletClassModel servletClassModel;
	public ServletNameModel getServletNameModel() {
		return servletNameModel;
	}
	public void setServletNameModel(ServletNameModel servletNameModel) {
		this.servletNameModel = servletNameModel;
	}
	public ServletClassModel getServletClassModel() {
		return servletClassModel;
	}
	public void setServletClassModel(ServletClassModel servletClassModel) {
		this.servletClassModel = servletClassModel;
	}
}

WebAppModel 类

package com.hyf.model.work;

import java.util.ArrayList;
import java.util.List;

public class WebAppModel {
    private   List<ServletModel> servletModels=new ArrayList<>();
    private   List<ServletMappingModel> servletMappingModels=new ArrayList<>();
    
    public  void pushServletModel(ServletModel servletModel) {
    	servletModels.add(servletModel);
    }
    public List<ServletModel> popServletModel() {
    	return servletModels;
    }
    
    //
    public void pushServletMappingModel(ServletMappingModel servletMappingModel) {
    	servletMappingModels.add(servletMappingModel);
    }
    public List<ServletMappingModel> popServletMappingModel(){
		return servletMappingModels;
    }
}

** WebAppModelFactory 工厂**

package com.hyf.model.work;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class WebAppModelFactory {

	/**
	 * 默认调用 xeb.xml
	 * 
	 * @return
	 * @throws Exception
	 */
	public static WebAppModel buildWebAppModel() throws Exception {
		return buildWebAppModel("web.xml");
	}

	/**
	 * 建模 需要改动的 资源文件
	 * 
	 * @param xmlPath
	 * @return
	 * @throws Exception
	 */
	public static WebAppModel buildWebAppModel(String xmlPath) throws Exception {
	    WebAppModel webAppModel=new WebAppModel();
		InputStream is = WebAppModelFactory.class.getResourceAsStream(xmlPath);
		SAXReader reader = new SAXReader();
		Document doc = reader.read(is);
		// 将 Servlet标签内容加入到 web-App中
		List<Element> servletEles = doc.selectNodes("web-app/servlet");
		for (Element servletEle : servletEles) {
			ServletModel servletModel=new ServletModel();
			
			// 获取标签内部的文本类容
			Element servletNameEle = (Element) servletEle.selectSingleNode("servlet-name");
			Element servletClasssEle = (Element) servletEle.selectSingleNode("servlet-class");
			// 设置到文本对象中
			ServletNameModel   servletNameModel=new ServletNameModel();
			servletNameModel.setValue(servletNameEle.getText());  // 把文本内容添加到对象中
			
			ServletClassModel servletClassModel=new ServletClassModel();
			servletClassModel.setValue(servletClasssEle.getText());
			
			// 在把上面的两个对象(ServletNameModel),(ServletClassModel)加入到 ServletModel
			servletModel.setServletNameModel(servletNameModel);
			servletModel.setServletClassModel(servletClassModel);
			
			//最后再把 servletModel 加入到 webApp中
			webAppModel.pushServletModel(servletModel);
		}

		// 给ServletMappingModel填充xml的内容
		 List<Element> servletMappingEles=doc.selectNodes("web-app/servlet-mapping");
		 for (Element servletMappingEle: servletMappingEles) {
			 ServletMappingModel servletMappingModel=new ServletMappingModel();
			 // 把servlet-name 标签文本内容放到(ServletNameModel)对象中,然后在加到webAppModel
			 Element servletNameEle=(Element)servletMappingEle.selectSingleNode("servlet-name");
			 ServletNameModel servletNameModel=new ServletNameModel();
			 servletNameModel.setValue(servletNameEle.getText());
			 servletMappingModel.setServletNameModel(servletNameModel);

			 //
			List<Element> servletUrlPatternEles=servletMappingEle.selectNodes("url-pattern");
			for (Element servletUrlPatternEle : servletUrlPatternEles) {
				UrlPatternModel urlPatternModel=new UrlPatternModel();
				urlPatternModel.setValue(servletUrlPatternEle.getText());
				servletMappingModel.push(urlPatternModel);
			}
			    webAppModel.pushServletMappingModel(servletMappingModel);
		}
		return webAppModel;
	}
	
	/**
	 *  通过url-pattern读取到servlet-class的值
	 *     :先通过url-pattern 获取到 servlet-name 值,在通过servlet-name 获取到servlet-class的值
	 * @param wam
	 * @param url
	 * @return
	 * 
	 */
	public static String getServletClassByUrl(WebAppModel wam,String url) {
		String servletClass = ""; // 最终返回的值
		String servletName="";    // name 值
		/*
		 * 找到网站对应的servlet-name 
		 */
		List<ServletMappingModel> servletMappingModels=wam.popServletMappingModel();
		for (ServletMappingModel servletMappingModel : servletMappingModels) {
			Set<UrlPatternModel> urlPatternModel=servletMappingModel .pop();
			for (UrlPatternModel urlPatternModel2 : urlPatternModel) {
				if(url.equals(urlPatternModel2.getValue())) {
					ServletNameModel servletNameModel=servletMappingModel.getServletNameModel();
					servletName=servletNameModel.getValue();
				}
			}
		}
		
		/*
		 * 找到servlet-name对应的后台处理类
		 */
		List<ServletModel> ServletModels=wam.popServletModel();
		for (ServletModel servletModel : ServletModels) {
               ServletNameModel  servletNameModel=servletModel.getServletNameModel();
               if(servletName.equals(servletNameModel.getValue())) {
            	  ServletClassModel  servletClassModel=servletModel.getServletClassModel();
            	  servletClass=servletClassModel.getValue();
              }
		}
		return servletClass;
	}
	
}

** Test 测试类**

package com.hyf.model.work;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Test {
	public static void main(String[] args) throws Exception {
		WebAppModel wam = WebAppModelFactory.buildWebAppModel();
		String str1 = WebAppModelFactory.getServletClassByUrl(wam, "/jrebelServlet");
		String str2 = WebAppModelFactory.getServletClassByUrl(wam, "/jrebelServlet2");
		String str3 = WebAppModelFactory.getServletClassByUrl(wam, "/jrebelServlet3");
		System.out.println("/jrebelServlet    "+str1);
		System.out.println("/jrebelServlet2   "+str2);
		System.out.println("/jrebelServlet3   "+str3);

	}
}

输出
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值