使用GSON解析JSON SCHEMA而不使用java中的预定义对象

时间:2016-07-21 11:28:49

标签: java json parsing jsonschema

需要有关如何解析JSON&#34的指导; SCHEMA "对于复杂对象,以便仅使用GSON创建键值对。我的目标是获取所有父子列表

Gson gson=new GsonBuilder().setPrettyPrinting().create();
JsonReader reader = new JsonReader(
    new InputStreamReader(
        new FileInputStream("C:\\Users\\ravr\\Desktop\\inputJSONSChema.json"), 
        "UTF-8"
    )
);

JsonParser parser = new JsonParser();
JsonObject parentObject=parser.parse( reader ).getAsJsonObject();
//parseJsonObjectRecursive(parentObject);

Map<String, Object> map = gson.fromJson(
    parentObject, 
    new TypeToken<Map<String, Object>>(){}.getType()
);

System.out.println(map);
Iterator<Map.Entry<String, Object>> mapItr=map.entrySet().iterator();

while(mapItr.hasNext()) {
    Map.Entry<String, Object> obj=(Entry<String, Object>) mapItr.next();
    System.out.println("Key->" + obj.getKey());

    if("properties".equalsIgnoreCase(obj.getKey())) {

    } else if("items".equalsIgnoreCase(obj.getKey())) {

    }
}

1 个答案:

答案 0 :(得分:0)

最后,我发现了一种肮脏的方式。

我创建了一个JSONSchemaElement pojo,它是具有parent child概念的通用pojo,并将向其添加元素。

public class JSONSchemaElement {

private String elementName;
private JsonSchemaTagEnum.ELEMENT_TYPE elementType;
private String elementValue;
private String minItems;
private String maxItems;
private boolean hasChildren;
private List<JSONSchemaElement> children = new ArrayList<>();



public void addChildElement(JSONSchemaElement childElement) {
    children.add( childElement );
}

/**
 * @return the elementName
 */
public String getElementName() {
    return elementName;
}

/**
 * @param elementName
 *            the elementName to set
 */
public void setElementName(String elementName) {
    this.elementName = elementName;
}

/**
 * @return the elementType
 */
public JsonSchemaTagEnum.ELEMENT_TYPE getElementType() {
    return elementType;
}

/**
 * @param elementType
 *            the elementType to set
 */
public void setElementType(JsonSchemaTagEnum.ELEMENT_TYPE elementType) {
    this.elementType = elementType;
}

/**
 * @return the elementValue
 */
public String getElementValue() {
    return elementValue;
}

/**
 * @param elementValue
 *            the elementValue to set
 */
public void setElementValue(String elementValue) {
    this.elementValue = elementValue;
}

/**
 * @return the minItems
 */
public String getMinItems() {
    return minItems;
}

/**
 * @param minItems
 *            the minItems to set
 */
public void setMinItems(String minItems) {
    this.minItems = minItems;
}

/**
 * @return the maxItems
 */
public String getMaxItems() {
    return maxItems;
}

/**
 * @param maxItems
 *            the maxItems to set
 */
public void setMaxItems(String maxItems) {
    this.maxItems = maxItems;
}

/**
 * @return the hasChildren
 */
public boolean isHasChildren() {
    return hasChildren;
}

/**
 * @param hasChildren
 *            the hasChildren to set
 */
public void setHasChildren(boolean hasChildren) {
    this.hasChildren = hasChildren;
}

/**
 * @return the children
 */
public List<JSONSchemaElement> getChildren() {
    return children;
}

/**
 * @param children
 *            the children to set
 */
public void setChildren(List<JSONSchemaElement> children) {
    this.children = children;
}

/*
 * (non-Javadoc)
 * 
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ( ( children == null ) ? 0 : children.hashCode() );
    result = prime * result + ( ( elementName == null ) ? 0 : elementName.hashCode() );
    result = prime * result + ( ( elementType == null ) ? 0 : elementType.hashCode() );
    result = prime * result + ( ( elementValue == null ) ? 0 : elementValue.hashCode() );
    result = prime * result + ( hasChildren ? 1231 : 1237 );
    result = prime * result + ( ( maxItems == null ) ? 0 : maxItems.hashCode() );
    result = prime * result + ( ( minItems == null ) ? 0 : minItems.hashCode() );
    return result;
}

/*
 * (non-Javadoc)
 * 
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object obj) {
    if ( this == obj ) {
        return true;
    }
    if ( obj == null ) {
        return false;
    }
    if ( getClass() != obj.getClass() ) {
        return false;
    }
    JSONSchemaElement other = (JSONSchemaElement) obj;
    if ( children == null ) {
        if ( other.children != null ) {
            return false;
        }
    }
    else if ( !children.equals( other.children ) ) {
        return false;
    }
    if ( elementName == null ) {
        if ( other.elementName != null ) {
            return false;
        }
    }
    else if ( !elementName.equals( other.elementName ) ) {
        return false;
    }
    if ( elementType != other.elementType ) {
        return false;
    }
    if ( elementValue == null ) {
        if ( other.elementValue != null ) {
            return false;
        }
    }
    else if ( !elementValue.equals( other.elementValue ) ) {
        return false;
    }
    if ( hasChildren != other.hasChildren ) {
        return false;
    }
    if ( maxItems == null ) {
        if ( other.maxItems != null ) {
            return false;
        }
    }
    else if ( !maxItems.equals( other.maxItems ) ) {
        return false;
    }
    if ( minItems == null ) {
        if ( other.minItems != null ) {
            return false;
        }
    }
    else if ( !minItems.equals( other.minItems ) ) {
        return false;
    }
    return true;
}

/*
 * (non-Javadoc)
 * 
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
    return "JSONSchemaElement [elementName=" + elementName + ", elementType=" + elementType + ", elementValue="
            + elementValue + ", minItems=" + minItems + ", maxItems=" + maxItems + ", hasChildren=" + hasChildren
            + ", children=" + children + "]";
}

}

然后在singleton类的以下方法中调用parseJsonSchema方法,如下所示。这里我们构造了RootNode,然后传递给递归方法parseJsonSchema。

JSONSchemaElement parentNode = null;
        try {
            JsonParser parser = new JsonParser();
            Preconditions.checkState( StringUtils.isNotEmpty( jsonSchema ), "JSON Schema Is NULL !!! " );
            JsonObject parentObject = parser.parse( jsonSchema ).getAsJsonObject();

            parentNode = new JSONSchemaElement();
            parentNode.setElementName( JsonSchemaTagEnum.ROOT_NODE.name() );
            parentNode.setHasChildren( true );
            parentNode.setElementType( JsonSchemaTagEnum.ELEMENT_TYPE.COMPLEX_TYPE );
            parseJSONSchema( parentObject, parentNode );

            if ( LOGGER.isDebugEnabled() ) {
                LOGGER.debug( "After Parsing element->" + parentNode );
            }
        }
        catch ( Exception e ) {
            LOGGER.error( e.getMessage(), e );
        }
        if ( LOGGER.isDebugEnabled() ) {
            LOGGER.debug(
                    "-------------------- JSONSchemaUtility:fetchDecomposedJSONSchemaElementFromJsonSchema:: END ----------------------------------" );
        }



/**
 * 
 * @param parentObject
 * @param parentlement
 */
private void parseJSONSchema(JsonObject parentObject, JSONSchemaElement parentlement) {

    Set<Map.Entry<String, JsonElement>> entries = parentObject.entrySet();
    for ( Map.Entry<String, JsonElement> entry : entries ) {
        JSONSchemaElement element = new JSONSchemaElement();
        if ( LOGGER.isDebugEnabled() ) {
            LOGGER.debug( "Entry Key->" + entry.getKey() );
            LOGGER.debug( "Entry VALUE->" + entry.getValue() );
        }
        if ( entry.getValue().isJsonObject() ) {
            String key = entry.getKey();
            element.setElementName( key.toUpperCase() );
            element.setElementType( JsonSchemaTagEnum.ELEMENT_TYPE.COMPLEX_TYPE );
            element.setHasChildren( true );
            if ( !rejectKeyList.contains( entry.getKey().toUpperCase() ) ) {
                setPrimitiveType( entry, element );

            }
            /**
             * create child
             */
            parseJSONSchema( entry.getValue().getAsJsonObject(), element );
            /**
             * Pull Element from bottom to this key=> items->properties->actual element as ITEMS,PROPERTIES TAGS of
             * JSON is not required
             */
            element = pullChildFromBottomToTop( parentlement, element, key );
            if ( LOGGER.isDebugEnabled() ) {
                LOGGER.debug( "************** Returning control back !!!!!!!!!!!" );
            }

        }
        else {
            if ( !JsonSchemaTagEnum.TYPE.name().equalsIgnoreCase( entry.getKey() ) ) {

                if ( JsonSchemaTagEnum.MIN_ITEMS.name().equalsIgnoreCase( entry.getKey() ) ) {
                    if ( entry.getValue().isJsonPrimitive() ) {
                        parentlement.setMinItems( entry.getValue().getAsString() );
                    }
                    else if ( entry.getValue().isJsonNull() ) {
                        parentlement.setMinItems( entry.getValue().getAsJsonNull().toString() );
                    }
                }
                else if ( JsonSchemaTagEnum.MAX_ITEMS.name().equalsIgnoreCase( entry.getKey() ) ) {
                    if ( entry.getValue().isJsonPrimitive() ) {
                        parentlement.setMaxItems( entry.getValue().getAsString() );
                    }
                    else if ( entry.getValue().isJsonNull() ) {
                        parentlement.setMaxItems( entry.getValue().getAsJsonNull().toString() );
                    }
                }
                else {
                    element.setElementName( entry.getKey().toUpperCase() );
                    element.setElementType( JsonSchemaTagEnum.ELEMENT_TYPE.SIMPLE_TYPE );
                    if ( entry.getValue().isJsonArray() ) {
                        element.setElementValue( entry.getValue().getAsJsonArray().toString() );
                    }
                    else if ( entry.getValue().isJsonPrimitive() ) {
                        element.setElementValue( entry.getValue().getAsString() );
                    }
                    else if ( entry.getValue().isJsonNull() ) {
                        element.setElementValue( entry.getValue().getAsJsonNull().toString() );
                    }
                    element.setHasChildren( false );
                }

            }

        }
        if ( null != element && null != element.getElementName() && element.getElementName().length() > 0 ) {
            parentlement.addChildElement( element );
        }

    }

}

/**
 * 
 * @param parentlement
 * @param element
 * @param key
 * @return
 */
private JSONSchemaElement pullChildFromBottomToTop(JSONSchemaElement parentlement, JSONSchemaElement element,
        String key) {
    if ( JsonSchemaTagEnum.PROPERTIES.name().equalsIgnoreCase( key )
            || JsonSchemaTagEnum.ITEMS.name().equalsIgnoreCase( key ) ) {
        if ( LOGGER.isDebugEnabled() ) {
            LOGGER.debug( "For Properties Type key->" + element );
        }
        parentlement.setChildren( element.getChildren() );
        element.setChildren( null );
        if ( JsonSchemaTagEnum.ITEMS.name().equalsIgnoreCase( key ) ) {
            if ( null == parentlement.getMinItems() ) {
                parentlement.setMinItems( element.getMinItems() );
            }
            if ( null == parentlement.getMaxItems() ) {
                parentlement.setMaxItems( element.getMaxItems() );
            }
        }
        element = null;

    }
    return element;
}

/**
 * 
 * @param entry
 * @param element
 */
private void setPrimitiveType(Map.Entry<String, JsonElement> entry, JSONSchemaElement element) {
    Gson gson = new Gson();
    String jsonTypeCasted = gson.toJson( entry.getValue() );
    String formattedJsonString = ( ( ( jsonTypeCasted.replaceAll( "\\{", "" ).trim() ).replaceAll( "\\}", "" )
            .trim() ).replaceAll( "\"", "" ) ).trim();
    String[] splitted = formattedJsonString.split( ":" );
    if ( splitted.length == 2 ) {
        String validPrimitiveType = isValidJsonPrimitiveDataType( splitted[1] );
        Preconditions.checkNotNull( validPrimitiveType,
                "Data Type Mentioned In JSON Schema Is Not Supported By JSON: Valid Primitive Data Type Are NUMBER,STRING,BOOLEAN" );
        element.setElementValue( validPrimitiveType.toUpperCase() );
        element.setElementType( JsonSchemaTagEnum.ELEMENT_TYPE.SIMPLE_TYPE );
        element.setHasChildren( false );
    }
    gson = null;
}

private String isValidJsonPrimitiveDataType(String inputPrimitiveType) {
    String jsonPrimitiveDataType = null;
    if ( JSON_DATA_TYPE.STRING.toString().equalsIgnoreCase( inputPrimitiveType ) ) {
        jsonPrimitiveDataType = JSON_DATA_TYPE.STRING.toString();
    }
    else if ( JSON_DATA_TYPE.NUMBER.toString().equalsIgnoreCase( inputPrimitiveType ) ) {
        jsonPrimitiveDataType = JSON_DATA_TYPE.NUMBER.toString();
    }
    else if ( JSON_DATA_TYPE.BOOLEAN.toString().equalsIgnoreCase( inputPrimitiveType ) ) {
        jsonPrimitiveDataType = JSON_DATA_TYPE.BOOLEAN.toString();
    }
    else {
        if ( LOGGER.isDebugEnabled() ) {
            LOGGER.debug( "This Data Type Is Not Supproted in JSON->" + inputPrimitiveType );
        }
        jsonPrimitiveDataType = null;
    }

    return jsonPrimitiveDataType;
}

}