自己的一点点思路,欢迎大家拍砖
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>