对接webservice项目需xml参数时,不吝指正:
//设置XStream编码格式
private static XStream xstream = new XStream(new DomDriver("GBK"));
/*
* xml请求模板 <objects> <object> ... </object> ... <object> </object> </objects>
*/
/**
* 集合对象转xml
* @param aliasObjects 集合类别名--objects 如果为空则取clazzObjects
* @param aliasObject 子类别名--object 如果为空则取clazzObject类名
* @param clazzObjects 集合类
* @param clazzObject 子类
* @param t 请求数据源(类型是clazzObjects)
* @return xml
*/
public static <T> String toXml(String aliasObjects, String aliasObject, Class<T> clazzObjects, Class<?> clazzObject,
T t) {
if (StringUtils.isBlank(aliasObjects)) {
aliasObjects = clazzObjects.getSimpleName().toLowerCase();
}
if (StringUtils.isBlank(aliasObject)) {
aliasObject = clazzObject.getSimpleName().toLowerCase();
}
xstream.alias(aliasObject, clazzObject);
xstream.alias(aliasObjects, clazzObjects);
xstream.addImplicitCollection(clazzObjects, Arrays.asList(clazzObjects.getDeclaredFields()).stream()
.reduce((first, second) -> second).get().getName());
return xstream.toXML(t);
}
注意: xml请求模板的标签(如:objects)严格与别名赋值(aliasObjects=objects)大小写一致,示例全部小写;此处XStream添加隐式集合时是利用反射(会影响性能)自动获取的集合类所定义的最后一个属性名称,也可以替换自定义名称,XStream源码如下:
/**
* Adds a default implicit collection which is used for any unmapped XML tag.
*
* @param ownerType class owning the implicit collection
* @param fieldName name of the field in the ownerType. This field must be a concrete
* collection type or matching the default implementation type of the collection
* type.
*/
public void addImplicitCollection(Class ownerType, String fieldName) {
addImplicitCollection(ownerType, fieldName, null, null);
}
需要的测试类:
class Test {
String a;
Integer b;
public Test(String a, Integer b) {
super();
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public Integer getB() {
return b;
}
public void setB(Integer b) {
this.b = b;
}
@Override
public String toString() {
return "Test [a=" + a + ", b=" + b + "]";
}
}
class TestList {
List<Test> list;
public TestList() {
list = Lists.newArrayList();
}
public void addAll(List<Test> ts) {
list.addAll(ts);
}
@Override
public String toString() {
return "TestList [list=" + list + "]";
}
测试使用:
public static void main(String[] args) {
TestList list = new TestList();
list.addAll(Lists.newArrayList(new Test("c", 1), new Test("d", 2)));
String xml = toXml(null, null, TestList.class, Test.class, list);
System.err.println(xml);
}
测试结果:
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=gasp
<testlist>
<test>
<a>c</a>
<b>1</b>
</test>
<test>
<a>d</a>
<b>2</b>
</test>
</testlist>
补充:有朋友说测试结果不是完整的xml无法直接当参数请求,瞬间//.其实测试结果少了xml标签头:<?xml version="1.0" encoding="GBK" ?>,那如何添加这玩意呢?一种是直接在返回String结果上拼接:"<?xml version=\"1.0\" encoding=\"GBK\"?>\n"
这种每次都得手动拼接比较麻烦,还有一种就是生成xml时自动拼接,一劳永逸,方便快捷;我们先学习下XStream源码:
/**
* Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed
* afterwards and in case of an exception.
*
* @throws XStreamException if the object cannot be serialized
*/
public void toXML(Object obj, Writer out) {
HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out);
try {
marshal(obj, writer);
} finally {
writer.flush();
}
}
他要求咱们传一个writer参数,这样咱们就好办了,把上面toXml方法进行修改,return xstream.toXml可以换成如下:
Writer writer = new StringWriter();
writer.write("<?xml version=\"1.0\" encoding=\"GBK\" ?>\n");
xstream.toXML(t, writer);
return writer.toString();
测试结果:
<?xml version="1.0" encoding="GBK" ?>
<test1>
<test>
<a>a</a>
<b>1</b>
</test>
<test>
<a>b</a>
<b>2</b>
</test>
</test1>
疗效刚好 !!