在前文中讲到了如何使用JSON标准库解析json串,参考:

Oracle解析复杂json的方法(转)

现补充一篇使用GSON库在Oracle中解析复杂json的方法。

GSON串的使用教程参考官方文档及

Gson使用一(Gson)

Gson使用二(GsonBuilder)

Gson使用三(集合的处理,一对多处理)

Gson使用四(TypeAdapter)

这一系列教程挺不错的,不过都使用了JavaBean,个人没有在Oracle里面直接使用JavaBean,GSON库提供了丰富的JsonElement处理方法。

1.执行loadjava命令导入处理json所需jar文件

  1. loadjava -r -f -u user/pwd@xxx.xxx.xxx.xxx:port/SID gson-2.8..jar

2.在数据库SQL窗口执行以下脚本,创建java源码对象

  1. create or replace and compile java source named "Cux_Gson_Util" as
  2.  
  3. import com.google.gson.JsonArray;
  4. import com.google.gson.JsonObject;
  5. import com.google.gson.JsonElement;
  6. import com.google.gson.JsonNull;
  7. import com.google.gson.JsonParseException;
  8. import com.google.gson.JsonParser;
  9. import com.google.gson.JsonPrimitive;
  10. import java.lang.Integer;
  11.  
  12. public class Cux_Gson_Util {
  13.  
  14. public static boolean isJsonString(String json) {
  15.  
  16. try {
  17. new JsonParser().parse(json);
  18. return true;
  19. } catch (JsonParseException e) {
  20. return false;
  21. } catch (NullPointerException e) {
  22. return false;
  23. } catch (Exception e) {
  24. return false;
  25. }
  26. }
  27.  
  28. // 取json串单个节点值
  29. //json取值,有两种常见的异常,KEY不存在,空指针异常,数组型json,数组长度越界异常
  30. //应该还是要按Exceptin处理,否则由于传参的数据错误的话,就发现不了,直接当空值返回了。
  31. //不能返回空,应该在第一步数据校验里面直接抛出来。
  32. public static String getValue(String jsonStr, String nodeName) {
  33. String nodeValue = "";
  34. if (!isJsonString(jsonStr)) {
  35. nodeValue = "";
  36. } else {
    try{
  37. JsonParser jsonParser = new JsonParser();
  38. JsonObject obj = new JsonObject();
  39. obj = (JsonObject) jsonParser.parse(jsonStr);
  40. nodeValue = "";
  41. if (obj.get(nodeName) instanceof JsonObject) {
  42. nodeValue = obj.get(nodeName).toString();
  43. } else if (obj.get(nodeName) instanceof JsonArray) {
  44. nodeValue = obj.get(nodeName).toString();
  45. } else if (obj.get(nodeName) instanceof JsonPrimitive) {
  46. // Error toString will , the result will start and end with "
  47. // nodeValue = obj.get(nodeName).toString();
  48.  
  49. // 四种写法都可以
  50. // nodeValue = obj.get(nodeName).getAsString();
  51. // nodeValue = obj.getAsString();
  52. // nodeValue =
  53. // obj.get(nodeName).getAsJsonPrimitive().toString();
  54. nodeValue = obj.get(nodeName).getAsJsonPrimitive().getAsString();
  55. } else if (obj.get(nodeName) instanceof JsonNull) {
  56. nodeValue = "";
  57. } else{
  58. nodeValue = obj.get(nodeName).getAsJsonPrimitive().getAsString();
  59. }
              }catch(Exception e){
              }
  60.  
  61. }
  62.  
  63. return nodeValue;
  64. }
  65.  
  66. //取json数组长度便于循环处理
  67. public static int getArrayLength(String jsonArrayStr){
  68. int length=0;
  69. if(isJsonString(jsonArrayStr)){
  70. JsonArray jsonArr = new JsonParser().parse(jsonArrayStr).getAsJsonArray();
  71. length=jsonArr.size();
  72. }else{
  73. length = 0;
  74. }
  75. return length;
  76. }
  77.  
  78. //取json数组第index个元素
  79. public static String getArrayValue(String jsonStr,Integer index){
  80. String nodeValue="";
  81. if(isJsonString(jsonStr)){
  82. JsonArray jsonArr = new JsonParser().parse(jsonStr).getAsJsonArray();
  83. //此处不能用getAsString()或者getAsJsonPrimitive(),因为数组中的类型未知,需要先做空判断
  84. if(jsonArr.get(index) instanceof JsonNull){
  85. nodeValue = "";
  86. }else{
  87. nodeValue = jsonArr.get(index).toString();
  88. }
  89. }else{
  90. nodeValue = null;
  91. }
  92.  
  93. return nodeValue;
  94. }
  95.  
  96. // 取json串下级节点值
  97. public static String getJsonValue(String jsonStr, String nodeName) {
  98. String nodeValue = "";
  99.  
  100. if (isJsonString(jsonStr)) {
  101. JsonParser parser = new JsonParser();
  102. JsonElement jsonElement = parser.parse(jsonStr);
  103.  
  104. if (jsonElement.isJsonNull()) {
  105. nodeValue = "";
  106. } else if (jsonElement.isJsonPrimitive()) {
  107. nodeValue = jsonElement.getAsJsonPrimitive().getAsString();
  108. } else if (jsonElement.isJsonObject()) {
  109. nodeValue = getJSONObjectValue(jsonElement.getAsJsonObject().toString(), nodeName);
  110. } else if (jsonElement.isJsonArray()) {
  111. nodeValue = getJSONArrayValue(jsonElement.getAsJsonArray().toString(), nodeName);
  112. } else {
  113. nodeValue = null;
  114. }
  115.  
  116. }
  117.  
  118. return nodeValue;
  119.  
  120. }
  121.  
  122. // 对于数组,以"@"作为分隔, index/nodeName形式,如 0@Amount
  123. public static String getJSONArrayValue(String jsonStr, String nodeName) {
  124. String nodeValue = "";
  125. JsonParser jsonParser = new JsonParser();
  126. JsonArray obj = jsonParser.parse(jsonStr).getAsJsonArray();
  127.  
  128. int position = nodeName.indexOf("@");
  129. String objStr = nodeName.substring(0, position);
  130. int index = Integer.parseInt(objStr);
  131. String nodeStr = nodeName.substring(position + 1);
  132. //此处未做数组越界异常判断,
  133.  
  134. nodeValue = getJsonValue(obj.get(index).toString(), nodeStr);
  135. return nodeValue;
  136. }
  137.  
  138. // 参数nodeName,对于嵌套json以"/"作为分隔,比如HEADER/LINE
  139. public static String getJSONObjectValue(String jsonStr, String nodeName) {
  140. String nodeValue = null;
  141. JsonParser jsonParser = new JsonParser();
  142. JsonObject obj = jsonParser.parse(jsonStr).getAsJsonObject();
  143.  
  144. int position = nodeName.indexOf("/");
  145. if (position == -1) {
  146. //此处未做Key是否存在的检查,如果要做,应该将检查方法单独提前校验
  147. if (obj.get(nodeName) instanceof JsonObject) {
  148. //此处可以直接用toString方法
  149. //nodeValue = obj.get(nodeName).toString();
  150. nodeValue = obj.get(nodeName).getAsJsonObject().getAsString();
  151. } else if (obj.get(nodeName) instanceof JsonArray) {
  152. //此处可以直接用toString方法
  153. //nodeValue = obj.get(nodeName).toString();
  154. nodeValue = obj.get(nodeName).getAsJsonArray().getAsString();
  155. } else if (obj.get(nodeName) instanceof JsonPrimitive) {
  156. nodeValue = obj.get(nodeName).getAsJsonPrimitive().getAsString();
  157. } else if (obj.get(nodeName) instanceof JsonNull) {
  158. nodeValue = "";
  159. } else {
  160. nodeValue = "";
  161. }
  162.  
  163. } else {
  164. String objStr = nodeName.substring(0, position);
  165. String nodeStr = nodeName.substring(position + 1);
  166. nodeValue = getJsonValue(obj.get(objStr).toString(), nodeStr);
  167. }
  168.  
  169. return nodeValue;
  170.  
  171. }
  172. }

3.利用步骤2创建的class创建function(或procedure),在此为了使其跟目前数据库已存在的json处理方法区分开,我们创建一个package,如下:

  1. CREATE OR REPLACE PACKAGE Cux_Gson_Util_pkg AS
  2. --// 取json串单个KEY值
  3. FUNCTION getval(jsonstr VARCHAR2, nodename VARCHAR2) RETURN VARCHAR2;
  4. --//取json数组第index个元素
  5. FUNCTION getarrval(jsonarraystr VARCHAR2, index_num NUMBER) RETURN VARCHAR2;
  6. --//取json数组长度便于循环处理
  7. FUNCTION getarrlen(jsonarraystr VARCHAR2) RETURN NUMBER;
  8.  
  9. --// 取json串下级节点值
  10. FUNCTION getjsonvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  11. RETURN VARCHAR2;
  12.  
  13. --// 对于数组,以"@"作为分隔, index/nodeName形式,如 0@Amount
  14. FUNCTION getjsonarrayvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  15. RETURN VARCHAR2;
  16.  
  17. --// 参数nodeName,对于嵌套json以"/"作为分隔,比如HEADER/LINE
  18. FUNCTION getjsonobjectvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  19. RETURN VARCHAR2;
  20.  
  21. END Cux_Gson_Util_pkg;
  22. /
  23. CREATE OR REPLACE PACKAGE BODY Cux_Gson_Util_pkg AS
  24. FUNCTION getval(jsonstr VARCHAR2, nodename VARCHAR2) RETURN VARCHAR2 AS
  25. LANGUAGE JAVA NAME 'Cux_Gson_Util.getValue(java.lang.String,java.lang.String) return java.lang.String';
  26.  
  27. FUNCTION getarrval(jsonarraystr VARCHAR2, index_num NUMBER) RETURN VARCHAR2 AS
  28. LANGUAGE JAVA NAME 'Cux_Gson_Util.getArrayValue(java.lang.String, java.lang.Integer) return java.lang.String';
  29.  
  30. FUNCTION getarrlen(jsonarraystr VARCHAR2) RETURN NUMBER AS
  31. LANGUAGE JAVA NAME 'Cux_Gson_Util.getArrayLength(java.lang.String) return java.lang.Integer';
  32.  
  33. FUNCTION getjsonvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  34. RETURN VARCHAR2 AS
  35. LANGUAGE JAVA NAME 'Cux_Gson_Util.getJsonValue(java.lang.String,java.lang.String) return java.lang.String';
  36.  
  37. FUNCTION getjsonarrayvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  38. RETURN VARCHAR2 AS
  39. LANGUAGE JAVA NAME 'Cux_Gson_Util.getJSONArrayValue(java.lang.String,java.lang.String) return java.lang.String';
  40.  
  41. FUNCTION getjsonobjectvalue(jsonarraystr VARCHAR2, nodename VARCHAR2)
  42. RETURN VARCHAR2 AS
  43. LANGUAGE JAVA NAME 'Cux_Gson_Util.getJSONObjectValue(java.lang.String,java.lang.String) return java.lang.String';
  44.  
  45. END Cux_Gson_Util_pkg;
  46. /

4.

测试

  1. SELECT cux_gson_util_pkg.getval('{"AA":"BB"}', 'AA') FROM DUAL;

结果
BB

  1. SELECT cux_18_gson_util_pkg.getarrval('[{"AA":"BB"}]', 0) FROM DUAL;

结果

{"AA":"BB"}

  1. SELECT cux_gson_util_pkg.getjsonvalue('[{"AA":"BB"}]', '0@AA') FROM DUAL;

结果

BB

  

Oracle 使用GSON库解析复杂json串的更多相关文章

  1. jsoncpp解析非json串

    转自:https://www.cnblogs.com/huojing/articles/5927488.html 由于Jsoncpp解析非法json时,会自动容错成字符类型.对字符类型取下标时,会触发 ...

  2. golang使用simplejson库解析复杂json

    cnblogs原创 golang自带的json解析库encoding/json提供了json字符串到json对象的相互转换,在json字符串比较简单的情况下还是挺好用的,但是当json字符串比较复杂或 ...

  3. gson在java和json串之间的应用

    public class JsonToJavaUtil { /** * 将json转成成javaBean对象 * * @param <T> * 返回类型 * @param json * 字 ...

  4. JMeter获取复杂的JSON串中的参数的值

    大家好,这篇博文中主要是介绍怎么用JMeter的BeanShell去获取复杂的JSON串中的某个参数的值,这将 便于我们用JMeter做出更完美的自动化测试: 首先有这样一个json串: { &quo ...

  5. 使用GSON和泛型解析约定格式的JSON串(转)

    时间紧张,先记一笔,后续优化与完善. 解决的问题: 使用GSON和泛型解析约定格式的JSON串. 背景介绍: 1.使用GSON来进行JSON串与java代码的互相转换. 2.JSON的格式如下三种: ...

  6. 开源 JSON 库解析性能对比( Jackson / Json.simple / Gson )

    Json 已成为当前服务器与 web 应用之间数据传输的公认标准. 微服务及分布式架构经常会使用 Json 来传输此类文件,因为这已经是 webAPI 的事实标准. 不过正如许多我们习以为常的事情一样 ...

  7. SpringMVC Jackson 库解析 json 串属性名大小写自动转换问题

    问题描述 在项目开发中,当实体类和表中定义的某个字段为 RMBPrice,首字母是大写的,sql 查询出来的列名也是大写的 RMBPrice,但是使用 jquery 的 ajax 返回请求响应时却出错 ...

  8. [转]用Gson来解析Json数据

    转自太阳尚远的博客:http://blog.yeqianfeng.me/2016/03/02/use_gson_to_parse_json/ 在我们实际开发中像Json和XML这两种格式的数据是最常见 ...

  9. JSON 串 自定义解析字段

    我们有时候会只需要j一个很长的json串中的少数的key value ,这个时候我们不会特意去建立一个object 来映射属性,这个时候我们可以应用 gson的JsonParser  来解析json串 ...

随机推荐

  1. mysql explicit_defaults_for_timestamp 变量的作用

    mysql 中有这样的一个默认行为,如果一行数据中某些列被更新了,如果这一行中有timestamp类型的列,那么么这个timestamp列的数据 也会被自动更新到 更新操作所发生的那个时间点:这个操作 ...

  2. linux查看内存free

    free 加参数-b/k//m/g,以b.k.m.g的大小显示结果,默认以k显示 [root@oldboy ~]# free total used free shared buffers cached ...

  3. Jsp获取Java的对象(JavaBean)

    Jsp获取Java的对象(JavaBean) Java代码片段: AuthReqBean authRep=new AuthReqBean(); authRep.setUserCode(usercode ...

  4. 根据wsdl文件,Web工程自动生成webservice客户端调用

    根据wsdl文件,Web工程自动生成webservice客户端调用 1,工具:带有webservice插件的eclips 2,步骤: (1),新建一个Web工程:WSDLTest (2),浏览器访问W ...

  5. Django 搭建后台 favicon.ico 文件操作

    Django 搭建后台 favicon.ico 文件操作 使用 django 搭建后台服务器,我用的是 django 1.8 版本以上的,就是路由不是 url 而是 path 的,这里有一个关于fav ...

  6. 03: JavaScript基础

    目录: 参考W3school 1.1 变量 1.2 JavaScript中数据类型 1.3 JavaScript中的两种for循环 1.4 条件语句:if.switch.while 1.5 break ...

  7. 20145334赵文豪网络对抗Web安全基础实践

    1.SQL注入攻击原理,如何防御? SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令的目的. 对于SQL注入攻击的防范,我觉 ...

  8. 字符编码之间的相互转换 UTF8与GBK(转载)

    转载自http://www.cnblogs.com/azraelly/archive/2012/06/21/2558360.html UTF8与GBK字符编码之间的相互转换 C++ UTF8编码转换 ...

  9. Python3基础 __delattr__ 在一个属性被删除时的行为

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. Eclipse中离线安装ADT插件详细教程

    在搭建Android开发环境的时候,我们需要为Eclipse安装ADT(Android Development Tools)插件,这个插件可以为用户提供一个强大的Android集成开发环境.通过给Ec ...