转:

net.sf.json.JSONObject处理 "null" 字符串的一些坑

2018年05月02日 16:41:25 大白能 阅读数:7026
 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28988969/article/details/80168447

添加依赖

  1. <dependency>
  2. <groupId>net.sf.json-lib</groupId>
  3. <artifactId>json-lib</artifactId>
  4. <version>2.4</version>
  5. <classifier>jdk15</classifier>
  6. </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

示例代码

  1. package com.ahut;
  2. import net.sf.json.JSONObject;
  3. import org.junit.Test;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import java.util.Map;
  6. @SpringBootTest
  7. public class ConfigClientApplicationTests {
  8. @Test
  9. public void contextLoads() {
  10. JSONObject jsonObject = new JSONObject();
  11. jsonObject.put("key", "null");
  12. jsonObject.put("key2", "notNull");
  13. Map itemsMap = (Map) jsonObject;
  14. System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull
  15. System.out.println(jsonObject.get("key2").getClass());//class java.lang.String
  16. System.out.println(itemsMap.get("key").equals("null"));//true
  17. System.out.println("null".equals(itemsMap.get("key")));//false
  18. System.out.println(itemsMap.get("key2").equals("notNull"));//true
  19. System.out.println("notNull".equals(itemsMap.get("key2")));//true
  20. }
  21. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

运行结果:

  1. class net.sf.json.JSONNull
  2. class java.lang.String
  3. true
  4. false
  5. true
  6. true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

代码分析

net.sf.json.JSONObject本身就实现了Map接口:

  1. public final class JSONObject extends AbstractJSON
  2. implements JSON, Map, Comparable {
  3. ...
  4. }
  • 1
  • 2
  • 3
  • 4

其内部维护了一个Map属性,实际就是一个HashMap:

  1. // 成员变量
  2. private Map properties;
  3. // 构造方法
  4. public JSONObject() {
  5. this.properties = new ListOrderedMap();
  6. }
  7. public ListOrderedMap() {
  8. this(new HashMap());
  9. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注意:

  • 非”null”字符串放到JSONObject类中时,取出来使用时是java.lang.String类型
  • “null”字符串放到JSONObject类中时,取出来的使用会转换成net.sf.json.JSONNull类型:
  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. package net.sf.json;
  6. import java.io.IOException;
  7. import java.io.Writer;
  8. public final class JSONNull implements JSON {
  9. private static JSONNull instance = new JSONNull();
  10. public static JSONNull getInstance() {
  11. return instance;
  12. }
  13. private JSONNull() {
  14. }
  15. public boolean equals(Object object) {
  16. return object == null || object == this || object == instance || object instanceof JSONObject && ((JSONObject)object).isNullObject() || "null".equals(object);
  17. }
  18. public int hashCode() {
  19. return 37 + "null".hashCode();
  20. }
  21. public boolean isArray() {
  22. return false;
  23. }
  24. public boolean isEmpty() {
  25. throw new JSONException("Object is null");
  26. }
  27. public int size() {
  28. throw new JSONException("Object is null");
  29. }
  30. public String toString() {
  31. return "null";
  32. }
  33. public String toString(int indentFactor) {
  34. return this.toString();
  35. }
  36. public String toString(int indentFactor, int indent) {
  37. StringBuffer sb = new StringBuffer();
  38. for(int i = 0; i < indent; ++i) {
  39. sb.append(' ');
  40. }
  41. sb.append(this.toString());
  42. return sb.toString();
  43. }
  44. public Writer write(Writer writer) {
  45. try {
  46. writer.write(this.toString());
  47. return writer;
  48. } catch (IOException var3) {
  49. throw new JSONException(var3);
  50. }
  51. }
  52. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

这就是为什么:

  1. System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull
  2. System.out.println(jsonObject.get("key2").getClass());//class java.lang.String
  • 1
  • 2
  • 3

itemsMap.get(“key”).equals(“null”)

分析:

  1. JSONObject jsonObject = new JSONObject();
  2. jsonObject.put("key", "null");
  3. Map itemsMap = (Map) jsonObject;
  4. System.out.println(itemsMap.get("key").equals("null"));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

键为 “key” 的值对应 “null” 字符串
所以itemsMap.get(“key”)获取到的类型是JSONNull
所以itemsMap.get(“key”).equals(“null”)中的equals调用的是JSONNull中的equals方法

  1. public boolean equals(Object object) {
  2. return object == null || object == this || object == instance || object instanceof JSONObject && ((JSONObject)object).isNullObject() || "null".equals(object);
  3. }
  • 1
  • 2
  • 3

所以:

  1. System.out.println(itemsMap.get("key").equals("null"));//true
  • 1

“null”.equals(itemsMap.get(“key”))

分析:

  1. JSONObject jsonObject = new JSONObject();
  2. jsonObject.put("key", "null");
  3. Map itemsMap = (Map) jsonObject;
  4. System.out.println("null".equals(itemsMap.get("key")));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

此时”null”.equals(itemsMap.get(“key”))调用的equals是String类的equals方法:


  1. /**
  2. * String复写的equals方法
  3. */
  4. public boolean equals(Object anObject) {
  5. // 比较地址是否相同,两个应用指向同一个对象(同一个地址)
  6. if (this == anObject) {
  7. return true;
  8. }
  9. // 判断是否是String类
  10. if (anObject instanceof String) {
  11. String anotherString = (String)anObject;
  12. int n = value.length;
  13. if (n == anotherString.value.length) {
  14. char v1[] = value;
  15. char v2[] = anotherString.value;
  16. int i = 0;
  17. while (n-- != 0) {
  18. if (v1[i] != v2[i])
  19. return false;
  20. i++;
  21. }
  22. return true;
  23. }
  24. }
  25. // 返回结果
  26. return false;
  27. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

执行分析:

  • itemsMap.get(“key”)获取到的是net.sf.json.JSONNull类型
  • net.sf.json.JSONNull和”null”不是同一个对象,继续向下执行
  • net.sf.json.JSONNull不是String类型,继续向下执行
  • return false

所以:

  1. System.out.println("null".equals(itemsMap.get("key")));//false

net.sf.json.JSONObject处理 "null" 字符串的一些坑的更多相关文章

  1. net.sf.json.JSONOBJECT.fromObject 与 com.alibaba.fastjson.JSONObject.parseObject

    文章待补充,先写写以下知识点好了. NULL值处理之 net.sf.json.JSONObject 和 com.alibaba.fastjson.JSONObject区别 JSON作为一个轻量级的文本 ...

  2. net.sf.json JSONObject与JSONArray使用实例

    实例自己想的一个实例应用场景:一个人可以有多个角色,例如:在家中是儿子,在学校是学生,在公司是程序员,一个人还可以办好多业务 * 每个业务好多个人都可以办,则标记(mark)就是记录这唯一标识的(如i ...

  3. 使用JSONObject遇到的问题,java.lang.NoClassDefFoundError: net/sf/json/JSONObject

    先是报 java.lang.NoClassDefFoundError: net/sf/json/JSONObject 这个错误, 打开项目属性找到java build path中的libaries,找 ...

  4. net.sf.json.JSONObject 和org.json.JSONObject 的差别

    http://my.oschina.net/wangwu91/blog/340721 net.sf.json.JSONObject 和org.json.JSONObject  的差别. 一.创建jso ...

  5. net.sf.json.JSONObject 和org.json.JSONObject

    参考 net.sf.json.JSONObject 和org.json.JSONObject 的差别

  6. net.sf.json JSONObject与JSONArray总结

    JSONObject:json对象,就是一个键对应一个值,使用的是大括号{ },如:{key:value} JSONArray:json数组,使用中括号[ ],只不过数组里面的项也是json键值对格式 ...

  7. net.sf.json.JSONObject maven下载到了但是java后台一直用不了问题

    需求,实体转JSON,然后用到JSONObject转JSON,但是我向下面这样引入,后台就是用不了,还是报红, <dependency> <groupId>net.sf.jso ...

  8. 记一次未解决的异常:java.lang.NoClassDefFoundError: net/sf/json/JSONObject

    原因:Jetty会导致这个问题,Tomcat可以正常启动   一.异常产生现象 使用json-lib转换实体类/字符串,跑单元测试没问题,但是启动jetty后调用JSONArray.fromObjec ...

  9. Jetty+json-lib库抛异常的问题解决过程(java.lang.NoClassDefFoundError: net/sf/json/JSONObject)

      一.之前抛异常是将json库改成了fastjson解决的,参见: http://www.cnblogs.com/gossip/p/5369670.html     异常信息:     二.解决步骤 ...

随机推荐

  1. JLINK驱动版本更换

    https://www.segger.com/downloads/jlink/JLink_Windows_V644b.exe 官网版本 Jlink的版本目录C:\Keil_v5\ARM\Segger\ ...

  2. NB-IOT无线帧结构和下行物理信道

    NB-IOT Downlink OFDM参数 1.下行基于OFDMA, FF点数=128,基带采样速率1.92MHz,子载波间距15kHz,有效带宽180kHz=1PRB OFDMA: 正交频分多址, ...

  3. 菜鸟宝典之Windows Server 2012 R2上PHP、MySQL环境搭建

    原文来自:https://www.jb51.net/article/59280.htm 上车准备一.准备工具服务器操作系统:Windows Server 2012PHP版本:5.6.9(根据自己需要) ...

  4. Select,poll,epoll复用

    Select,poll,epoll复用 1)select模块以列表的形式接受四个参数,分别是可读对象,可写对象,产生异常的对象,和超时设置.当监控符对象发生变化时,select会返回发生变化的对象列表 ...

  5. Hadoop_07_HDFS的Java API 操作

    通过Java API来访问HDFS 1.Windows上配置环境变量 解压Hadoop,然后把Hadoop的根目录配置到HADOOP_HOME环境变量里面 然后把HADOOP_HOME/lib和HAD ...

  6. 【SDOI2018】反回文串(【ARC064 F】Rotated Palindromes 加强版)

    题意 给你一个正整数 \(n\),求有多少字符集为 \(1\) 到 \(k\) 之间整数的字符串,使得该字符串可以由一个长度为 \(n\) 的回文串循环移位得到. ARC原题 \(100\%\) 的数 ...

  7. 最简单之在线安装mysql

    1,下载Repo wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 2,安装repo .n ...

  8. charindex函数--->检索字符在字符串中的起始位置

    语法:CHARINDEX(检索字符,被检索字符串) 返回值:检索字符在被检索字符串中的起始位置.

  9. C#与数据库有关的控件和属性

    BindingNavigator  数据记录导航 BindingSource 与数据源绑定, 常用属性:DataSource.DataMember 常用方法: DataGridView 以表格形式显示 ...

  10. wind本地MySQL数据到hive的指定路径,Could not create file

    一:使用:kettle:wind本地MySQL数据到hive的指定路径二:问题:没有root写权限网上说的什么少jar包,我这里不存在这种情况,因为我自己是导入jar包的:mysql-connecto ...