我们项目中可能会用到许多的json框架,Fastjson、jackson、Gson、orgjson、json-lib,其实现方式各不相同,接口Api就不一样,我们想换一个json框架改动的地方就会很多。参考SLF4J的思想,我统一了json框架的调用方式。
https://github.com/xiongshiyan/common-json
首先定义了顶层的json接口,可以代表jsonobject、jsonarray。
package cn.zytx.common.json; /** * 代表一个JsonObject/JsonArray * @author xiongshiyan at 2018/6/10 */ public interface Json<T extends Json> { /** * Json对象转换为字符串 */ @Override String toString(); @Override boolean equals(Object other); @Override int hashCode(); /** * 解析Json字符串 * @param jsonString Json字符串 * @return JsonObject或者JsonArray */ T parse(String jsonString); /** * 是否严格,像Json没有键而去获取是抛异常还是返回Null * @return true if isStrict */ default boolean isStrict(){return true;} /** * 设置是否严格 * @param isStrict true if isStrict */ T setStrict(boolean isStrict); /** * 具体的实现类 */ Object unwrap(); }
其下定义了代表jsonobject和jsonarray的cn.zytx.common.json.JsonObject和cn.zytx.common.json.JsonArray接口,不同的json框架去实现此接口。其实现类为cn.zytx.common.json.impl.JSONObject和cn.zytx.common.json.impl.JSONArray。注意所有的框架实现,这两个类名不变。于是调用方完全不用修改代码。
package cn.zytx.common.json; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Map; import java.util.Set; /** * 代表一个Json Object * @author xiongshiyan at 2018/6/10 */ public interface JsonObject extends Json<JsonObject>, Serializable{ /////////////////////get-related method//////////////////////// Object get(String key); Object get(String key, Object defaultObject); JsonObject getJsonObject(String key); JsonArray getJsonArray(String key); String getString(String key); String getString(String key, String defaultValue); Boolean getBoolean(String key); Boolean getBoolean(String key, Boolean defaultValue); Integer getInteger(String key); Integer getInteger(String key, Integer defaultValue); Long getLong(String key); Long getLong(String key, Long defaultValue); Float getFloat(String key); Float getFloat(String key, Float defaultValue); Double getDouble(String key); Double getDouble(String key, Double defaultValue); BigInteger getBigInteger(String key); BigInteger getBigInteger(String key, BigInteger defaultValue); BigDecimal getBigDecimal(String key); BigDecimal getBigDecimal(String key, BigDecimal defaultValue); <T> T get(String key, Class<T> clazz); ///////////////////////map-related method//////////////////////// Set<String> keySet(); int size(); boolean isEmpty(); boolean containsKey(String key); boolean containsValue(Object value); void clear(); Object remove(String key); JsonObject fromMap(Map<String, Object> map); /////////////////////put/change-related method//////////////////////// JsonObject put(String key, Object value); JsonObject putAll(Map<? extends String, ? extends Object> m); }
package cn.zytx.common.json; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.List; /** * 代表一个Json Array * @author xiongshiyan at 2018/6/10 */ public interface JsonArray extends Json<JsonArray>{ int size(); Object get(int index); String getString(int index); Boolean getBoolean(int index); Integer getInteger(int index); Long getLong(int index); Double getDouble(int index); Float getFloat(int index); BigInteger getBigInteger(int index); BigDecimal getBigDecimal(int index); JsonObject getJsonObject(int index); JsonArray getJsonArray(int index); JsonArray remove(int index); JsonArray clear(); JsonArray put(Object o); JsonArray put(int index, Object o); JsonArray putAll(Collection<?> os); JsonArray fromList(List<Object> list); }
其中JsonObject还实现了Serializable接口用于序列化JavaBean为String和反序列化。
package cn.zytx.common.json; /** * 序列化,反序列化能力 * @author xiongshiyan at 2018/6/10 */ public interface Serializable { /** * 序列化,把一个JavaBean序列化为String */ String serialize(Object javaBean); /** * 反序列化,把一个字符串反序列化为一个JavaBean */ <T> T deserialize(String jsonString, Class<T> clazz); }
一个BaseJson用于处理一些公共的代码
package cn.zytx.common.json.impl; import cn.zytx.common.json.Json; import cn.zytx.common.json.JsonException; /** * 提供一些公共的校验方法和特性,子类负责实现 * @author xiongshiyan at 2018/6/11 */ public abstract class BaseJson<T extends Json> { private boolean isStrict = true; private boolean isTolerant = true; public boolean isStrict(){return isStrict;} public T setStrict(boolean isStrict){this.isStrict = isStrict; return (T)this;} public boolean isTolerant(){return isTolerant;} public T setTolerant(boolean isTolerant){ this.isTolerant = isTolerant; return (T)this; } protected void assertKey(String key){ if(null == key){ throw new IllegalArgumentException("key 不能为空"); } } protected <R> R checkNullValue(String key , R o) { if(null == o){ if(isStrict()){ throw new JsonException("不存在key->" + key); }else { return null; } } return o; } protected <R> R checkNullValue(int index , R o) { if(null == o){ if(isStrict()){ throw new JsonException("不存在->[ " + index + " ]"); }else { return null; } } return o; } protected void assertIndex(int index , int size){ //越界 if(index < 0 || index >= size){ //严格模式 if(isStrict()){ throw new JsonException(new ArrayIndexOutOfBoundsException("index must between 0 and " + size)); } } } }