剖析XML和JSON内容的一点技能
概述
在没有统一标准的状况下,一个体系对接多个外部体系往往会碰到要求接口相应数据异构的状况,有能够返回的是XML,也有能够返回
JSON。除了返回范例差别,内容构造也不尽相同。以XML范例为例,
接口1返回内容
<root> <bizKey>16112638767472747178067</bizKey> <returnMsg>OK</returnMsg> <returnCode>200</returnCode> ... </root>
接口2返回内容
<root> <bid>16112638767472747178068</bid> <note>胜利</note> <returnStatus>1</returnStatus> ... </root>
假如在我们体系中为每种花样的内容针对处置惩罚显然是不合理的,上面的内容中我们只是体贴三种信息,分别是营业ID、状态值和形貌信息,那末可不能够笼统这三种信息,
取得这些信息后再进行营业逻辑处置惩罚。
剖析XML和JSON
依据营业笼统我们须要从XML也许JSON内容中取得三种信息,我们这里将会运用XPath和JSONPath的体式格局来剖析。比方取得接口1的主要信息,
我们能够设定三个XPath表达式,
{ bid: "/root/bizKey", code: "/root/returnCode", description: "/root/returnMsg" }
bid
,code
和description
对应我们体系本身定义的字段名。
剖析JSON内容也是同理的,只不过定义的是JSONPath表达式。
分两步走处置惩罚数据内容
假定我们从原始的XML和JSON数据中取得了bid
,code
和description
信息,
从接口1取得
{ bid: '16112638767472747178067', code: '200', description: 'OK' }
从接口2取得
{ bid: '16112638767472747178068', code: '1', description: '胜利' }
假定我们从接口1文档获知状态值200
示意要求胜利,从接口2文档获知状态值1
示意要求胜利,虽然他们都示意要求胜利,然则我们照样不能
把他们原原本本地保存到我们的营业相干表中(固然这些相应数据照样须要保存到别的的纪录表中的,最少轻易排查题目)。
假定我们的营业相干表是如许设想的
字段名 | 范例 | 形貌 |
---|---|---|
bid | string | 营业ID |
code | int | 状态值,0=初始,1=要求中,2=胜利,3=失利 |
description | string | 形貌 |
因而,我们还必须定义划定规矩把接口1返回的状态值200
转换为我们体系的2
,把接口2返回的状态值1
转换为我们体系的2
。
总结一下,两步走剖析XML和JSON数据内容
依据XPath也许JSONPath表达式剖析取得主要信息
依据划定规矩转换状态值
第一步剖析数据取得主要信息
以XML为例,
public class XmlParseUtils { private DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); private XPathFactory xpathFactory = XPathFactory.newInstance(); /** * * @param param 数据内容 * @param paths 表达式 * @return * @throws Exception */ public Map<String,Object> parse(String param, Map<String,String> paths) throws Exception{ InputSource inputSource = new InputSource(new StringReader(param)); Document document = dbFactory.newDocumentBuilder().parse(inputSource); Map<String,Object> map = Maps.newHashMap(); for(String key : paths.keySet()) { XPath xpath = xpathFactory.newXPath(); Node node = (Node) xpath.evaluate(paths.get(key), document, XPathConstants.NODE); if(node == null) { throw new Exception("node not found, xpath is " + paths.get(key)); } map.put(key, node.getTextContent()); } return map; } }
parse
函数的返回范例也能够是Map<String,String>
,临时用Map<String,Object>
。
第二步依据划定规矩转换状态值
这一步稍稍有点贫苦,不过我们先不斟酌代码完成,横竖你能想到的能够他人已帮你完成了。起首我们依据接口文档定义划定规矩,写出划定规矩表达式(也许其他的什么),
又是表达式。假定接口1的返回的状态值比较简朴,只要200
示意胜利,其他状况都是失利,那末我们能够如许定义划定规矩,
code.equals("200") ? 2: 3
也许
<#if code == "200"> 2 <#else> 3 <#/if>
亦也许
function handle(arg) { if(arg == 200) { return 2; } return 3; } handle(${code})
以上依据统一份文档定义了三种差别范例的状态值转换划定规矩,一定须要三种差别的完成。下面逐一申明,
三目表达式
code.equals("200") ? 2: 3
是一个三目表达式,我们将运用jexl
引擎来剖析,应用第一步剖析数据取得主要信息的效果,我们能够如许做
public Object evaluateByJexl(String expression, Map<String,Object> context) { JexlEngine jexl = new JexlBuilder().create(); JexlExpression e = jexl.createExpression(expression); JexlContext jc = new MapContext(context); return e.evaluate(jc); }
FreeMarker模板
<#if code == "200"> 2 <#else> 3 <#/if>
处置惩罚这段模板我们能够这么做
/** * * @param param FreeMarker模板 * @param context * @return * @throws Exception */ public String render(String param, Map<String,Object> context) throws Exception { Configuration cfg = new Configuration(); StringTemplateLoader stringLoader = new StringTemplateLoader(); stringLoader.putTemplate("myTemplate",param); cfg.setTemplateLoader(stringLoader); Template template = cfg.getTemplate("myTemplate","utf-8"); StringWriter writer = new StringWriter(); template.process(context, writer); return writer.toString(); }
假如FreeMarker
模板比较庞杂,从模板预编译成Template
能够会斲丧更多的机能,就要斟酌把Template
缓存起来。
JavaScript代码段
function handle(arg) { if(arg == 200) { return 2; } return 3; } handle(${code})
这段js
代码中存在${code}
,起首它须要运用FreeMarker
衬着获得真正的handle
要领的挪用参数,然后
public Object evaluate(String expression) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); return engine.eval(expression); }
ScriptEngineManager
的机能预计不太乐观,毕竟是一个言语的引擎。
差别转换划定规矩完成的比较
范例 | 完成 | 长处 | 瑕玷 |
---|---|---|---|
三目表达式 | Jexl | 简朴(easy) | 简朴(simple) |
FreeMarker模板 | FreeMarker | -- | -- |
JavaScript代码段 | FreeMarker + ScriptEngine | 直观 | 历程庞杂,机能题目 |
看起来Freemarker
是一个不错的挑选。
至此两步走小技能已完成了,都是应用了现成的代码完成。
也许我们会如许的应战,在做状态值转换时须要晓得当前体系某个营业状态值的状况,
此时Freemarker
表达式多是如许的,
<# assign lastCode = GetLastCode(code)> <#if lastCode == "2"> 2 <#elseif code == "200"> 2 <#else> 3 <#/if>
这里我们能够运用Freemarker的特征,自定义Java函数或东西类,在模板中挪用。
以上就是剖析XML和JSON内容的一点技能的实例代码分享的细致内容,更多请关注ki4网别的相干文章!