以模板方式处理数据接口

自己的一点点思路,欢迎大家拍砖

1.    背景

需要为第三方提供数据接口

此数据接口的特点为:接口特别多,需要为每个功能都提供数据接口

2.     设计目标

1)XML作为数据的载体

2)开发人员在源代码中可以清晰的获得数据接口的结构

3)数据接口具有较强的扩展性

3.     设计思路

1)开发前先定义好接口模板,程序启动时将接口模板加载到内存中

2)内存中构造出与接口模板想匹配的数据模型,见数据模型与接口模板进行数据绑定

4.      实现

Entity.java  实体类,与接口模板进行数据绑定

TemplateConfig.java  模板配置类,用于将模板文件加载到内存中

TemplateXML.java  XML模板处理类,生成数据接口

error.xml  数据接口模板  绑定规则  type属性默认为string;type=list 代表集合;type=entity代表实体;dataName 对应实体中的key

 

public final class Entity {
	
	private Map<String, Object> genericValue = new HashMap<String, Object>();
	
	public Entity put(String key, Object value){
		genericValue.put(key, value);
		return this;
	}
	
	public Object get(String key){
		return genericValue.get(key);
	}
	
	public String getString(String key){
		try {
			return (String)genericValue.get(key);
		} catch (ClassCastException e) {
			return "Null";
		}
	}
	
	public Entity getEnttiy(String key){
		try {
			return (Entity)genericValue.get(key);
		} catch (ClassCastException e) {
			return new Entity();
		}
	}
}
 
public class TemplateConfig {
	
	public static Map<String, Document> templates = null;
	private static File fileDirector = null;
	private static InputStream is = null;
	
	static {
		templates = new HashMap<String, Document>();
		fileDirector = new File(TemplateConfig.class.getClass().getResource("/config/template").getPath());
	}
	
	public static void init() throws TemplateException{
		load(fileDirector);
		try {
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void load(File fileDirector) throws TemplateException{
		if (fileDirector.isDirectory()){
			for (File file : fileDirector.listFiles()){
				if (file.isDirectory()){
					load(file);
				}else{
					templates.put(file.getName(), getDocument(file));
				}
			}
		}
	}
	
	public static Document getDocument(File file) throws TemplateException{
		try {
			is = new FileInputStream(file);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		try {
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			throw new TemplateException(e);
		}
		try {
			return builder.parse(is);
		} catch (SAXException e) {
			e.printStackTrace();
			throw new TemplateException(e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new TemplateException(e);
		}
	}
}
public class TemplateXML implements Template{
	private InputStream is = null;
	private Entity entity = null;
	private Document templateDoc = null;
	
	public TemplateXML(InputStream templateStream, Entity entity){
		this.entity = entity;
		this.is = templateStream;
	}
	
	public TemplateXML(Document templateDoc, Entity entity){
		this.templateDoc = templateDoc;
		this.entity = entity;
	}
	
	public void process() throws Exception{
		Element templateRoot = templateDoc.getDocumentElement();
		NodeList templateNodeList = templateRoot.getChildNodes();
		parserNodeList(templateNodeList, entity);
	}
	
	private Document getDocument(InputStream is) throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		return builder.parse(is);
	}
	
	private void parserNodeList(NodeList nodeList, Entity entity) throws Exception{
		for (int i =0; i< nodeList.getLength(); i++){
			Node node = nodeList.item(i);
			if ("#text".equals(node.getNodeName())) continue;
			String nodeType = "";
			String dataName = "";
			try {
				nodeType = node.getAttributes().getNamedItem("type").getNodeValue();
			} catch (NullPointerException e) {
				nodeType = Template.TYPE_STRING;
			}
			try {
				dataName = node.getAttributes().getNamedItem("dataName").getNodeValue();
				node.getAttributes().removeNamedItem("dataName");
			} catch (NullPointerException e) {
				dataName = node.getNodeName();
			}
			if (Template.TYPE_LIST.equals(nodeType)){
				Entity nodeEntity = entity.getEnttiy(dataName);
				this.parserNodeList(node.getChildNodes(), nodeEntity);
			}else if (Template.TYPE_ENTITY.equals(nodeType)){
				Entity nodeEntity = entity.getEnttiy(dataName);
				this.parserNodeList(node.getChildNodes(), nodeEntity);
			}else {
				String nodeValue = entity.getString(dataName);
				node.setTextContent(nodeValue);
			}
		}
	}
	
	public static void main(String [] args) throws Exception{
		Entity e = new Entity();
		e.put("errorTip", "a");
		e.put("errorCode", "b");
		e.put("errorMsg", "c");
		e.put("dse_operationName", "d");
		e.put("pkgId", "e");
		e.put("contact", new Entity().put("phone", "123").put("address", "beijing"));
		Entity ads = new Entity();
		ads.put("ad", new Entity().put("simg", "simg1").put("bimg", "bimg1"));
		e.put("ads", ads);
		
		TemplateConfig.init();
		TemplateXML tx = new TemplateXML(TemplateConfig.templates.get("error.xml"), e);
		
		tx.process();
		TransformerFactory tf = TransformerFactory.newInstance();  
        Transformer t = tf.newTransformer();
        ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
        t.transform(new DOMSource(tx.templateDoc), new StreamResult(bos));
        System.out.println(bos.toString().replaceAll("\r\n|\t", ""));
	}

}

 

 <?xml version="1.0" encoding="UTF-8"?>

<res>
	<errorTip dataName="errorTip"/>
	<errorCode dataName="errorCode"/>
	<errorMsg dataName="errorMsg"/>
	<operationName dataName="operationName"/>
	<ads dataName="ads" type="list">
		<ad dataName="ad" type="entity">
			<simg dataName="simg"/>
			<bimg dataName="bimg"/>
		</ad>
	</ads>
	<contact type="entity">
		<phone dataName="phone"/>
		<address dataName="address"/>
	</contact>
</res>

结果:

<?xml version="1.0" encoding="UTF-8"?><res><errorTip>a</errorTip><errorCode>b</errorCode><errorMsg>c</errorMsg><dse_operationName>d</dse_operationName><pkgId>e</pkgId><ads type="list"><ad type="entity"><simg>simg1</simg><bimg>bimg1</bimg></ad></ads><contact type="entity"><phone>123</phone><address>beijing</address></contact></res>
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值