fastjson java 字段排序_「Java」 - xml & Json 排序输出
项目封装了新的SDK,需要对SDK进行测试,API没有变更。
设计一自动化CASE:
- 通过openapi的方式调用YAPI上接口测试用例,返回结果A;
- 引入SDK,编写单元测试代码,通过SDK调用接口,返回结果B;
- 对结果(xml/Json)进行排序后断言。
因为整个环境只有SDK是新的,所以完成以上CASE,基本可以找出SDK中存在的Bug。
但是返回结果中xml和Json的属性顺序不一定相对,所以用基本的equals可能会存在判断不准确的情况,需要提前对结果进行自然排序,排序后进行比较即可。
一、Json排序
fastjson,使用SerializerFeature.MapSortField参数,可以达到目的。
@Slf4j
public class FastJsonSortTest
{
@Test
public void testSortJson()
{
String json = "";
JSONObject jsonObject = JSON.parseObject(json);
String rs = JSON.toJSONString(jsonObject, SerializerFeature.MapSortField, SerializerFeature.PrettyFormat);
log.info("rn{}", rs);
}
}
二、xml排序
xml比较复杂,这里只讨论POJO<->xml的形式。
对于比较POJO形式的xml根据node名称进行自然排序即可,使用XSLT进行sort即可。
@Slf4j
public class XmlSortTest
{
@Test
public void testSorXml() throws Exception
{
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource("E:Mediff-xmlsrcmainresourcessort.xsl"));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
transformer.transform(new StreamSource("E:Mediff-xmlsrcmainresources2.xml"), new StreamResult(outputStream));
log.info("rn{}", (outputStream.toString()));
}
}
对应的xsl文件。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="name()"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
手工调整xml中结点位置,对于生成的结果文件进行比较,完全一致。
三、XML排序 - 续
好悲剧啊,接口返回的xml信息太复杂了,以至于XSLT模板比较难配置,该方案最终折戟。这里还是把即将删除的代码记录一下。
@Scan
@Slf4j
public class SortXml
{
@Conf("sort.xsl")
private static String xsltFile;
/**
* 使用XSLT对xml进行排序
*/
public static String sort(String xml)
{
// XSLT模板文件,放置于test目录下的resouces中
try
{
InputStream xsltIn = FileUtil.getFileInputStream(xsltFile);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltIn));
ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
transformer.transform(new StreamSource(inputStream), new StreamResult(outputStream));
return outputStream.toString();
}
catch (Exception e)
{
log.error("SortXml处理异常,{}", xml, e);
}
return null;
}
}
XSLT增加结点过滤。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" encoding="GBK"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="name()"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!--过滤结点-->
<xsl:template match="time|password"/>
</xsl:stylesheet>
四、XMLUnit
终极方案,XMLUnit,不多解释了。
https://www.xmlunit.org/
https://github.com/xmlunit/xmlunit
http://xmlunit.sourceforge.net/userguide/XMLUnit-Java.pdf
探究 XMLUnit
XMLUnit: 验证比较XML文件的工具
五、FastJson最终处理
实在是写不动了,还是贴代码了。
对于Json中也需要对部分字段进行忽略,可以使用filter进行过滤。
public class JsonCompareUtil
{
@Conf("ignore.node.name")
private static String ignoreNodeNameStr = "time,resultElapse,productImg";
private static SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
static
{
String[] ignoreNodeNames = JsonCompareUtil.ignoreNodeNameStr.split(",|,");
for (String ignoreNodeName : ignoreNodeNames)
{
filter.getExcludes().add(ignoreNodeName);
}
}
private static String jsonFilter(String json)
{
JSONObject jsonObject = JSON.parseObject(json);
String rs = JSON.toJSONString(jsonObject, filter, SerializerFeature.MapSortField, SerializerFeature.PrettyFormat);
return rs;
}
public static boolean compare(String jsonSource, String jsonCompareWith)
{
jsonSource = jsonFilter(jsonSource);
jsonCompareWith = jsonFilter(jsonCompareWith);
return jsonSource.equals(jsonCompareWith);
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)