2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 解析XML和JSON内容的一点技巧的实例代码分享

解析XML和JSON内容的一点技巧的实例代码分享

时间:2022-10-25 18:02:36

相关推荐

解析XML和JSON内容的一点技巧的实例代码分享

XML/RSS教程

XML,JSON

XML/RSS教程

mmonly女性网站源码,右键去除vscode打开,ubuntu 日志文件,运行tomcat命令,sqlite 时间段查找,爬虫如何抓取付费图片psd格式,短网址php源码,seo学习培训运营,网站首页被放弹窗,淘宝网页滚动图片代码,织梦模板安装不全lzw

解析XML和JSON内容的一点技巧

概述

相册书商城源码,ubuntu退出不了文件,能飞的爬虫,线下php,北京seo后海lzw

在没有统一标准的情况下,一个系统对接多个外部系统往往会遇到请求接口响应数据异构的情况,有可能返回的是XML,也有可能返回

JSON。除了返回类型不同,内容结构也不尽相同。以XML类型为例,

接口1返回内容

h5游戏源码在微信发布,vscode源文件报错,修改ip ubuntu,tomcat mac版本,sqlite3查看数据库中的表,网页设计 失败,连接数据库和网页,ping服务器,搜索时间插件,中国开发的前端框架是什么,钦州爬虫,php接收数组,seo实践,springboot无网络,标签选择器.,网站源码程序,网页 flash素材,discuz 模板视频教程,zen cart后台空白,程序启动页面,教务管理系统cs,卡盟程序lzw

16112638767472747178067 OK 200 ...

接口2返回内容

16112638767472747178068 成功 1 ...

如果在我们系统中为每种格式的内容针对处理显然是不合理的,上面的内容中我们只是关心三种信息,分别是业务ID、状态值和描述信息,那么可不可以抽象这三种信息,

获得这些信息后再进行业务逻辑处理。

解析XML和JSON

根据业务抽象我们需要从XML或者JSON内容中获得三种信息,我们这里将会使用XPath和JSONPath的方式来解析。比如获得接口1的重要信息,

我们可以设定三个XPath表达式,

{ bid: "/root/bizKey", code: "/root/returnCode", description: "/root/returnMsg"}

bid,codedescription对应我们系统自己定义的字段名。

解析JSON内容也是同理的,只不过定义的是JSONPath表达式。

分两步走处理数据内容

假设我们从原始的XML和JSON数据中获得了bid,codedescription信息,

从接口1获得

{ bid: 16112638767472747178067, code: 200, description: OK}

从接口2获得

{ bid: 16112638767472747178068, code: 1, description: 成功}

假设我们从接口1文档获知状态值200表示请求成功,从接口2文档获知状态值1表示请求成功,虽然他们都表示请求成功,但是我们还是不能

把他们原原本本地保存到我们的业务相关表中(当然这些响应数据还是需要保存到另外的记录表中的,至少方便排查问题)。

假设我们的业务相关表是这样设计的

因此,我们还必须定义规则把接口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 parse(String param, Map paths) throws Exception{ InputSource inputSource = new InputSource(new StringReader(param)); Document document = dbFactory.newDocumentBuilder().parse(inputSource); Map 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,暂且用Map

第二步根据规则转换状态值

这一步稍稍有点麻烦,不过我们先不考虑代码实现,反正你能想到的可能别人已经帮你实现了。首先我们根据接口文档定义规则,写出规则表达式(或者其他的什么),

又是表达式。假设接口1的返回的状态值比较简单,只有200表示成功,其他情况都是失败,那么我们可以这样定义规则,

code.equals("200") ? 2: 3

或者

23

亦或者

function handle(arg) { if(arg == 200) { return 2; } return 3;}handle(${code})

以上根据同一份文档定义了三种不同类型的状态值转换规则,肯定需要三种不同的实现。下面一一说明,

三目表达式

code.equals("200") ? 2: 3是一个三目表达式,我们将使用jexl引擎来解析,利用第一步解析数据获得重要信息的结果,我们可以这样做

public Object evaluateByJexl(String expression, Map context) { JexlEngine jexl = new JexlBuilder().create(); JexlExpression e = jexl.createExpression(expression); JexlContext jc = new MapContext(context); return e.evaluate(jc); }

FreeMarker模板

23

处理这段模板我们可以这么做

/**** @param param FreeMarker模板* @param context* @return* @throws Exception*/ public String render(String param, Map 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的性能估计不太乐观,毕竟是一个语言的引擎。

不同转换规则实现的比较

看起来Freemarker是一个不错的选择。

至此两步走小技巧已经实现了,都是利用了现成的代码实现。

或许我们会这样的挑战,在做状态值转换时需要知道当前系统某个业务状态值的情况,

此时Freemarker表达式可能是这样的,

223

这里我们可以使用Freemarker的特性,自定义Java函数或工具类,在模板中调用。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。