Webservice交互中需要双方约定数据格式,用XML表示数据库记录是不错的选择。
先定义个DTD:
<!--
DTD for the Xml-Format-String used to transmit business data
-->
<!-- The "DBSET" element is the root of the Xml-Format-String-->
<!ELEMENT DBSET ( R* )>
<!ATTLIST DBSET RESULT #IMPLIED>
<!-- The "R" element describes a record-->
<!ELEMENT R ( C+ )>
<!-- The "C" element describes a column-->
<!ELEMENT C ( #PCDATA ) >
<!ATTLIST C N #REQUIRED>
用R代表ROW,C代表COLUMN,N代表NAME(R、C和N降低了可读性,但节约了传输字节数)
数据库记录示例:
FIRST_NAME LAST_NAME
1 seng tang
2 wukong sun
XML示例:
<?xml version='1.0' encoding='UTF-8'?>
<DBSET RESULT="2">
<R>
<C N="firstName">wukong</C>
<C N="lastName">sun</C>
</R>
<R>
<C N="firstName">sen</C>
<C N="lastName">tang</C>
</R>
</DBSET>
再来个嵌套的示例:
<DBSET>
<R>
<C N="province">浙江</C>
<C N="cityList">
<DBSET>
<R>
<C N="en">HangZhou</C>
<C N="zh">杭州</C>
<R>
<R>
<C N="en">JinHua</C>
<C N="zh">金华</C>
<R>
</DBSET>
</C>
<R>
</DBSET>
有个这个可以表示任何复杂的业务数据。
剩下的问题就是XML的组成及解析了。
用一个专门的类负责组织及解析XML,组装XML方法的参数为Map(一个R节点)或List<Map>(多个R节点)
同样解析后的结果为Map(一个R节点)或List<Map>(多个R节点),
这样开发直接打交道的就是Map或List<Map>了(Map和List可是很容易操作的哦)。
接下来看看解析工具
以前我是用Dom4j解析的,后来改成了用Stax,经测试,速度较前者提高了1-2倍。
Axis2宣称比Axis1速度快了很多,很大程度上归功于XML的解析改为了Stax的方式吧。
关于Stax的使用网上有很多的,由于性能要求高,我用的是Streaming Api,jar是Axis2中带的(顺便说下Axis2的部署吓死人,太多东西而实际上很多用不到),
两个jar:geronimo-stax-api_1.0_spec-1.0.1.jar 和wstx-asl-3.2.4.jar
晒代码:
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import epm.core.exception.EPMRuntimeException;
/** *//**
* Utility class to convert one Object to Xml-Format-String and back again. The
* Xml-Format-String is based on the following DTD.<p/> <code>
* <!-- The "DBSET" element is the root of the Xml-Format-String--> <br/>
* <!ELEMENT DBSET ( R* )> <br/>
* <!ATTLIST DBSET RESULT #IMPLIED> <p/>
* <!-- The "R" element describes a record--> <br/>
* <!ELEMENT R ( C+ )> <p/>
* <!-- The "C" element describes a column--> <br/>
* <!ELEMENT C ( #PCDATA ) > <br/>
* <!ATTLIST C N #REQUIRED> <p/></code>
*
*
* Author: jinn*/
public class XfsUtil {
// ----------------------------- Construct one Object to Xml-Format-String
public static String toXfs(Object object) {
if (object == null) {
return null;
} else if (object instanceof List) {
return toXfs((List) object);
} else if (object instanceof Map) {
return toXfs((Map) object);
} else {
StringWriter buffer = new StringWriter();
XMLStreamWriter writer = createStartDocument(buffer);
try {
writer.writeStartElement("DBSET");
writer.writeAttribute("RESULT", object.toString());
writer.writeEndElement();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return docAsXml(writer, buffer);
}
}
public static String toXfs(Map map) {
StringWriter buffer = new StringWriter();
XMLStreamWriter writer = createStartDocument(buffer);
try {
writer.writeStartElement("DBSET");
addMapToRowElement(map, writer);
writer.writeEndElement();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return docAsXml(writer, buffer);
}
public static String toXfs(List<Map> mapList) {
StringWriter buffer = new StringWriter();
XMLStreamWriter writer = createStartDocument(buffer);
addListToDbsetElement(mapList, writer);
return docAsXml(writer, buffer);
}
private static XMLStreamWriter createStartDocument(StringWriter buffer) {
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces",
new Boolean(true));
XMLStreamWriter writer = null;
try {
writer = outputFactory.createXMLStreamWriter(buffer);
writer.writeStartDocument("UTF-8", "1.0");
writer.writeCharacters("\r\n");
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return writer;
}
private static String docAsXml(XMLStreamWriter writer, StringWriter buffer) {
try {
writer.writeEndDocument();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return buffer.toString();
}
private static void addMapToRowElement(Map map, XMLStreamWriter writer) {
try {
writer.writeStartElement("R");
Iterator keyValuePairs = map.entrySet().iterator();
for (int i = 0; i < map.size(); i++) {
Map.Entry entry = (Map.Entry) keyValuePairs.next();
String key = (String) entry.getKey();
Object value = entry.getValue();
writer.writeStartElement("C");
writer.writeAttribute("N", key);
if (value == null || value instanceof String) {
writer.writeCharacters(value == null ? "" : (String) value);
} else if (value instanceof List) {
addListToDbsetElement((List) value, writer);
} else {
writer.writeCharacters(value.toString());
}
writer.writeEndElement();
}
writer.writeEndElement();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void addListToDbsetElement(List srcList,
XMLStreamWriter writer) {
try {
writer.writeStartElement("DBSET");
writer.writeAttribute("RESULT", Integer.toString(srcList.size()));
Iterator it = srcList.iterator();
while (it.hasNext()) {
Map map = (Map) it.next();
addMapToRowElement(map, writer);
}
writer.writeEndElement();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// ----------------------------- parese Xml-Format-String to one Object
public static int getDbsetAttribute(String xmlStr) {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
String result = "0";
XMLStreamReader reader = null;
try {
reader = inputFactory
.createXMLStreamReader(new StringReader(xmlStr));
while (reader.hasNext()) {
if (dbsetStart(reader)) {
result = reader.getAttributeValue(0);
break;
}
reader.next();
}
} catch (XMLStreamException e) {
e.printStackTrace();
throw new EPMRuntimeException("server.badXmlStr",
new String[] { xmlStr });
} finally {
try {
reader.close();
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
return Integer.parseInt(result);
}
public static List<Map> toList(String xmlStr) {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
List list = new ArrayList();
try {
XMLStreamReader reader = inputFactory
.createXMLStreamReader(new StringReader(xmlStr));
list = paresDbsetElementToList(reader);
reader.close();
} catch (XMLStreamException e) {
e.printStackTrace();
throw new EPMRuntimeException("server.badXmlStr",
new String[] { xmlStr });
}
return list;
}
private static List paresDbsetElementToList(XMLStreamReader reader) {
List list = new ArrayList();
Map map = new HashMap();
try {
while (reader.hasNext()) {
if (rowStart(reader)) {
map = parseRowElementToMap(reader, list);
} else if (dbsetEnd(reader)) {
break;
}
reader.next();// 获取下一个解析事件
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
private static Map parseRowElementToMap(XMLStreamReader reader, List list) {
Map map = new HashMap();
try {
while (reader.hasNext()) {
int eventType = reader.getEventType();
if (colStart(reader)) {
String key = reader.getAttributeValue(0);
Object value;
try {
String colText = reader.getElementText();
value = (colText == null || "null"
.equalsIgnoreCase(colText)) ? "" : colText;
} catch (Exception e) {
reader.next();
value = paresDbsetElementToList(reader);
}
map.put(key, value);
} else if (rowEnd(reader)) {
list.add(map);
break;
}
reader.next();// 获取下一个解析事件
}
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
private static boolean dbsetStart(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.START_ELEMENT
&& "DBSET".equals(reader.getLocalName());
}
private static boolean dbsetEnd(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.END_ELEMENT
&& "DBSET".equals(reader.getLocalName());
}
private static boolean rowStart(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.START_ELEMENT
&& "R".equals(reader.getLocalName());
}
private static boolean rowEnd(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.END_ELEMENT
&& "R".equals(reader.getLocalName());
}
private static boolean colStart(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.START_ELEMENT
&& "C".equals(reader.getLocalName());
}
private static boolean colEnd(XMLStreamReader reader) {
return reader.getEventType() == XMLStreamReader.END_ELEMENT
&& "C".equals(reader.getLocalName());
}
public static void main(String[] args) throws XMLStreamException {
List list = new ArrayList();
Map map = new HashMap();
map.put("firstName", "wukong");
map.put("lastName", "sun");
list.add(map);
Map map2 = new HashMap();
map2.put("firstName", "sen");
map2.put("lastName", "tang");
list.add(map2);
Map m = new HashMap();
m.put("nested", list);
String dataXmlStr = toXfs(list);
System.out.println(dataXmlStr);
List parsedList = toList(dataXmlStr);
System.out.println("result:" + parsedList);
}
}
posted on 2008-07-18 15:13
jinn 阅读(2037)
评论(1) 编辑 收藏 所属分类:
Jave/Webservice