一个通用的Json解析框架接口设计(一)-接口设计

时间:2022-04-04 12:56:10

我们项目中可能会用到许多的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.JSONObjectcn.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));
            }
        }
    }
}