From 6b27653a995e97e355e2b0a318ae220d553253eb Mon Sep 17 00:00:00 2001 From: redkale Date: Sat, 15 Jul 2023 08:12:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0JsonString=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/convert/json/JsonArray.java | 319 +++++++++++++- .../org/redkale/convert/json/JsonEntity.java | 8 +- .../org/redkale/convert/json/JsonObject.java | 394 +++++++++++++++++- .../org/redkale/convert/json/JsonString.java | 84 ++++ 4 files changed, 802 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/redkale/convert/json/JsonString.java diff --git a/src/main/java/org/redkale/convert/json/JsonArray.java b/src/main/java/org/redkale/convert/json/JsonArray.java index 752c14f50..8dcde5fd4 100644 --- a/src/main/java/org/redkale/convert/json/JsonArray.java +++ b/src/main/java/org/redkale/convert/json/JsonArray.java @@ -3,9 +3,10 @@ */ package org.redkale.convert.json; +import java.math.*; import java.util.*; import org.redkale.convert.ConvertDisabled; -import org.redkale.util.Utility; +import org.redkale.util.*; /** * 常规json数组 @@ -41,6 +42,316 @@ public class JsonArray extends ArrayList implements JsonEntity { return (JsonArray) JsonEntityDecoder.instance.convertFrom(new JsonReader(text, offset, length)); } + public JsonArray append(Object value) { + super.add(value); + return this; + } + + public JsonArray append(int index, Object value) { + super.set(index, value); + return this; + } + + public boolean isNull(int index) { + return get(index) == null; + } + + public boolean isJsonObject(int index) { + return get(index) instanceof JsonObject; + } + + public boolean isJsonArray(int index) { + return get(index) instanceof JsonArray; + } + + public JsonObject getJsonObject(int index) { + Object val = get(index); + if (val instanceof JsonObject) { + return (JsonObject) val; + } + if (val instanceof Map) { + return new JsonObject((Map) val); + } + throw new RedkaleException("val [" + val + "] is not a valid JsonObject."); + } + + public JsonArray getJsonArray(int index) { + Object val = get(index); + if (val instanceof JsonArray) { + return (JsonArray) val; + } + if (val instanceof Collection) { + return new JsonArray((Collection) val); + } + throw new RedkaleException("val [" + val + "] is not a valid JsonArray."); + } + + public String getString(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + return val.toString(); + } + + public String getString(int index, String defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + return val.toString(); + } + + public BigDecimal getBigDecimal(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof BigDecimal) { + return (BigDecimal) val; + } + return new BigDecimal(val.toString()); + } + + public BigDecimal getBigDecimal(int index, BigDecimal defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof BigDecimal) { + return (BigDecimal) val; + } + try { + return new BigDecimal(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public BigInteger getBigInteger(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof BigInteger) { + return (BigInteger) val; + } + return new BigInteger(val.toString()); + } + + public BigInteger getBigInteger(int index, BigInteger defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof BigInteger) { + return (BigInteger) val; + } + try { + return new BigInteger(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Number getNumber(int index) { + Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return (Number) val; + } + return JsonObject.stringToNumber(val.toString()); + } + + public Number getNumber(int index, Number defValue) { + Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return (Number) val; + } + try { + return JsonObject.stringToNumber(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Double getDouble(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).doubleValue(); + } + return Double.parseDouble(val.toString()); + } + + public double getDouble(int index, double defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).doubleValue(); + } + try { + return Double.parseDouble(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Long getLong(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).longValue(); + } + return Long.parseLong(val.toString()); + } + + public long getLong(int index, long defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).longValue(); + } + try { + return Long.parseLong(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Float getFloat(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).floatValue(); + } + return Float.parseFloat(val.toString()); + } + + public float getFloat(int index, float defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).floatValue(); + } + try { + return Float.parseFloat(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Integer getInt(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).intValue(); + } + return Integer.parseInt(val.toString()); + } + + public int getInt(int index, int defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).intValue(); + } + try { + return Integer.parseInt(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Short getShort(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).shortValue(); + } + return Short.parseShort(val.toString()); + } + + public short getShort(int index, short defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).shortValue(); + } + try { + return Short.parseShort(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Byte getByte(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).byteValue(); + } + return Byte.parseByte(val.toString()); + } + + public byte getByte(int index, byte defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).byteValue(); + } + try { + return Byte.parseByte(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Boolean getBoolean(int index) { + final Object val = get(index); + if (val == null) { + return null; + } + return "true".equalsIgnoreCase(val.toString()); + } + + public boolean getBoolean(int index, boolean defValue) { + final Object val = get(index); + if (val == null) { + return defValue; + } + return "true".equalsIgnoreCase(val.toString()); + } + @Override @ConvertDisabled public final boolean isObject() { @@ -53,6 +364,12 @@ public class JsonArray extends ArrayList implements JsonEntity { return true; } + @Override + @ConvertDisabled + public final boolean isString() { + return false; + } + @Override public String toString() { return JsonConvert.root().convertTo(this); diff --git a/src/main/java/org/redkale/convert/json/JsonEntity.java b/src/main/java/org/redkale/convert/json/JsonEntity.java index 1ac41e272..574965967 100644 --- a/src/main/java/org/redkale/convert/json/JsonEntity.java +++ b/src/main/java/org/redkale/convert/json/JsonEntity.java @@ -20,6 +20,8 @@ public interface JsonEntity extends java.io.Serializable { public boolean isArray(); + public boolean isString(); + public static JsonEntity convertFrom(String text) { return convertFrom(Utility.charArray(text)); } @@ -29,7 +31,11 @@ public interface JsonEntity extends java.io.Serializable { } public static JsonEntity convertFrom(char[] text, final int offset, final int length) { - return JsonEntityDecoder.instance.convertFrom(new JsonReader(text, offset, length)); + Object val = JsonEntityDecoder.instance.convertFrom(new JsonReader(text, offset, length)); + if (val instanceof CharSequence) { + return new JsonString(val.toString()); + } + return (JsonEntity) val; } } diff --git a/src/main/java/org/redkale/convert/json/JsonObject.java b/src/main/java/org/redkale/convert/json/JsonObject.java index eeed38bb7..ed951a7d5 100644 --- a/src/main/java/org/redkale/convert/json/JsonObject.java +++ b/src/main/java/org/redkale/convert/json/JsonObject.java @@ -3,9 +3,10 @@ */ package org.redkale.convert.json; +import java.math.*; import java.util.*; import org.redkale.convert.ConvertDisabled; -import org.redkale.util.Utility; +import org.redkale.util.*; /** * 常规json对象 @@ -37,6 +38,391 @@ public class JsonObject extends LinkedHashMap implements JsonEnt return (JsonObject) JsonEntityDecoder.instance.convertFrom(new JsonReader(text, offset, length)); } + public static JsonObject of(Object javaBean) { + return convertFrom(JsonConvert.root().convertTo(javaBean)); + } + + public JsonObject append(String key, Object value) { + super.put(key, value); + return this; + } + + public JsonObject putObject(String key) { + JsonObject val = new JsonObject(); + super.put(key, val); + return val; + } + + public JsonArray putArray(String key) { + JsonArray val = new JsonArray(); + super.put(key, val); + return val; + } + + public boolean has(String key) { + return containsKey(key); + } + + public boolean isNull(String key) { + return get(key) == null; + } + + public boolean isJsonObject(String key) { + return get(key) instanceof JsonObject; + } + + public boolean isJsonArray(String key) { + return get(key) instanceof JsonArray; + } + + public JsonObject getJsonObject(String key) { + Object val = get(key); + if (val instanceof JsonObject) { + return (JsonObject) val; + } + if (val instanceof Map) { + return new JsonObject((Map) val); + } + throw new RedkaleException("val [" + val + "] is not a valid JsonObject."); + } + + public JsonArray getJsonArray(String key) { + Object val = get(key); + if (val instanceof JsonArray) { + return (JsonArray) val; + } + if (val instanceof Collection) { + return new JsonArray((Collection) val); + } + throw new RedkaleException("val [" + val + "] is not a valid JsonArray."); + } + + public String getString(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + return val.toString(); + } + + public String getString(String key, String defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + return val.toString(); + } + + public BigDecimal getBigDecimal(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof BigDecimal) { + return (BigDecimal) val; + } + return new BigDecimal(val.toString()); + } + + public BigDecimal getBigDecimal(String key, BigDecimal defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof BigDecimal) { + return (BigDecimal) val; + } + try { + return new BigDecimal(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public BigInteger getBigInteger(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof BigInteger) { + return (BigInteger) val; + } + return new BigInteger(val.toString()); + } + + public BigInteger getBigInteger(String key, BigInteger defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof BigInteger) { + return (BigInteger) val; + } + try { + return new BigInteger(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Number getNumber(String key) { + Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return (Number) val; + } + return stringToNumber(val.toString()); + } + + public Number getNumber(String key, Number defValue) { + Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return (Number) val; + } + try { + return stringToNumber(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Double getDouble(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).doubleValue(); + } + return Double.parseDouble(val.toString()); + } + + public double getDouble(String key, double defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).doubleValue(); + } + try { + return Double.parseDouble(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Long getLong(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).longValue(); + } + return Long.parseLong(val.toString()); + } + + public long getLong(String key, long defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).longValue(); + } + try { + return Long.parseLong(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Float getFloat(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).floatValue(); + } + return Float.parseFloat(val.toString()); + } + + public float getFloat(String key, float defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).floatValue(); + } + try { + return Float.parseFloat(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Integer getInt(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).intValue(); + } + return Integer.parseInt(val.toString()); + } + + public int getInt(String key, int defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).intValue(); + } + try { + return Integer.parseInt(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Short getShort(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).shortValue(); + } + return Short.parseShort(val.toString()); + } + + public short getShort(String key, short defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).shortValue(); + } + try { + return Short.parseShort(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Byte getByte(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + if (val instanceof Number) { + return ((Number) val).byteValue(); + } + return Byte.parseByte(val.toString()); + } + + public byte getByte(String key, byte defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + if (val instanceof Number) { + return ((Number) val).byteValue(); + } + try { + return Byte.parseByte(val.toString()); + } catch (Exception e) { + return defValue; + } + } + + public Boolean getBoolean(String key) { + final Object val = get(key); + if (val == null) { + return null; + } + return "true".equalsIgnoreCase(val.toString()); + } + + public boolean getBoolean(String key, boolean defValue) { + final Object val = get(key); + if (val == null) { + return defValue; + } + return "true".equalsIgnoreCase(val.toString()); + } + + protected static Number stringToNumber(String val) { + char initial = val.charAt(0); + if ((initial >= '0' && initial <= '9') || initial == '-') { + // decimal representation + if (val.indexOf('.') > -1 || val.indexOf('e') > -1 || val.indexOf('E') > -1 || "-0".equals(val)) { + // Use a BigDecimal all the time so we keep the original + // representation. BigDecimal doesn't support -0.0, ensure we + // keep that by forcing a decimal. + try { + BigDecimal bd = new BigDecimal(val); + if (initial == '-' && BigDecimal.ZERO.compareTo(bd) == 0) { + return -0.0; + } + return bd; + } catch (NumberFormatException retryAsDouble) { + // this is to support "Hex Floats" like this: 0x1.0P-1074 + try { + Double d = Double.valueOf(val); + if (d.isNaN() || d.isInfinite()) { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + return d; + } catch (NumberFormatException ignore) { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + } + } + // block items like 00 01 etc. Java number parsers treat these as Octal. + if (initial == '0' && val.length() > 1) { + char at1 = val.charAt(1); + if (at1 >= '0' && at1 <= '9') { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + } else if (initial == '-' && val.length() > 2) { + char at1 = val.charAt(1); + char at2 = val.charAt(2); + if (at1 == '0' && at2 >= '0' && at2 <= '9') { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + } + // integer representation. + // This will narrow any values to the smallest reasonable Object representation + // (Integer, Long, or BigInteger) + + // BigInteger down conversion: We use a similar bitLength compare as + // BigInteger#intValueExact uses. Increases GC, but objects hold + // only what they need. i.e. Less runtime overhead if the value is + // long lived. + BigInteger bi = new BigInteger(val); + if (bi.bitLength() <= 31) { + return bi.intValue(); + } + if (bi.bitLength() <= 63) { + return bi.longValue(); + } + return bi; + } + return null; + } + @Override @ConvertDisabled public final boolean isObject() { @@ -49,6 +435,12 @@ public class JsonObject extends LinkedHashMap implements JsonEnt return false; } + @Override + @ConvertDisabled + public final boolean isString() { + return false; + } + @Override public String toString() { return JsonConvert.root().convertTo(this); diff --git a/src/main/java/org/redkale/convert/json/JsonString.java b/src/main/java/org/redkale/convert/json/JsonString.java new file mode 100644 index 000000000..75e171ada --- /dev/null +++ b/src/main/java/org/redkale/convert/json/JsonString.java @@ -0,0 +1,84 @@ +/* + * + */ +package org.redkale.convert.json; + +import org.redkale.convert.ConvertDisabled; + +/** + * 常规json字符串 + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * @since 2.8.0 + */ +public class JsonString implements CharSequence, JsonEntity, Comparable { + + private String value; + + public JsonString() { + } + + public JsonString(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @ConvertDisabled + public boolean isNull() { + return value == null; + } + + @Override + public int length() { + return value.length(); + } + + @Override + public char charAt(int index) { + return value.charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) { + return value.substring(end, end); + } + + @Override + public int compareTo(JsonString o) { + return o == null ? -1 : CharSequence.compare(this, o.getValue()); + } + + @Override + @ConvertDisabled + public final boolean isObject() { + return false; + } + + @Override + @ConvertDisabled + public final boolean isArray() { + return false; + } + + @Override + @ConvertDisabled + public final boolean isString() { + return true; + } + + @Override + public String toString() { + return value; + } + +}