开发者

Why is json behaving in this weird manner?

Is there any reserve words for JSON as a KEY?

my Json structure is

dimObject{String:String}
finalObject(String:dimObject}

Line1# JSONObject dimObject=new JSONObject()
Line2# dimObject.put("class",["A","B","c"]);
Line3# dimObject.put("name",["sam"]);
Line4# System.out.print("dimObject#"+dimObject.toString());
Line5# JSONObject finalObject=new new JSONObect();
Line6# finalObject("supplier",dimObject);
Line7# System.out.print("finalObject#"+finalObject.toString());

OUTPUT:

dimObject#{"class":["A","B","c"],"name":["sam"]}
finalObject#{"supplier":{"name":["sam"]}}

So the problem is why my json is behaving in a weird manner.

I have not defined "class" as variable name, it's just a Key.

Problem is ,if an argument is given like,"class" is a key or reserve word then how i successfully inserted in Line#2,and if its insert able in dimObject then why its not insert able in finalObject.

Please help me solving this mystery

EXACT CODE::

public JSONObject getRequiredAttributesWithValues() {
        List<UserConstraint> constraintList = new ArrayList<UserConstraint>();
        Map<String, FactTableOptimizingInfo> factTableMap = MappingInfo.INSTANCE.
                getFactTableUserNameToFactTableOptimizingInfoMap();
        Map<String, DimensionTableInfo> dimTableMap = MappingInfo.INSTANCE.getDimTableRealNameToObjectMap();
        JSONObject requiredAttributes = getRequiredAttributes();
        JSONObject finalObject = new JSONObject();
        for (Object dimName : requiredAttributes.keySet()) {
            JSONObject dimObject = new JSONObject();
            JSONArray colNames = requiredAttributes.getJSONArray((String) dimName);
            for (Object colName : colNames) {
                List<String> columnList = new ArrayList<String>();
                String dimensionName = (String) dimName;
                String columnName = (String) colName;
                constraintList = new ArrayList<UserConstraint>();
                for (FilterDataStructure filter : this.info.getGlobalFilterList()) {
                    if (filter.getDimName().equals(dimensionName)) {
                        if (filter.getColumnName().equals(columnName)) {
                            AtomicConstraint.ConstraintType type;
                            try {
                                Integer.parseInt(filter.getValue());
                                type = AtomicConstraint.ConstraintType.INTEGER_TYPE;
                            } catch (NumberFormatException e) {
                                type = AtomicConstraint.ConstraintType.STRING_TYPE;
                            }
                            UserConstraint constraint = new UserAtomicConstraint(dimensionName, columnName, 
                                                        AtomicConstraint.getStringToOperator(filter.getOperator()),
                                                        filter.getValue(), type, factTableMap, dimTableMap);
                            constraintList.add(constraint);
                        }
                    }
                }

                columnList.add(columnName);
                List<UserDimensionInfoToBuildQuery> dimList = new ArrayList<UserDimensionInfoToBuildQuery>();
                UserTableAndColInfo groupByInfo = new UserTableAndColInfo(dimensionName, columnName);
                ArrayList<UserTableAndColInfo> groupByInfoList = new ArrayList<UserTableAndColInfo>();
                groupByInfoList.add(groupByInfo);

                UserDimensionInfoToBuildQuery dim = new UserDimensionInfoToBuildQuery(dimensionName, columnList);
                dimList.add(dim);
                UserInfoToBuildQuery.Builder queryBuilder = new UserInfoToBuildQuery.Builder(dimList).
                        groupBy(groupByInfoList);
                if (constraintList != null && !(constraintList.isEmpty())) {
                    if (constraintList.size() > 1) {
                        queryBuilder = queryBuilder.constraints(new UserComplexConstraint(constraintList,
                                ComplexConstraint.Joiner.AND));
                    } else {
                        queryBuilder = queryBuilder.constraints(constraintList.get(0));
                    }
                }
                List<Object> result = (List<Object>) DataAccessor.getData(queryBuilder.build());
                if (result == null) {
                    continue;
                }
                JSONArray valueArray = new JSONArray();

                for (Object row : result) {
                    List<Object> splitRow = (List<Object>) row;
                  开发者_运维知识库  valueArray.add(splitRow.get(0).toString());
                }
                dimObject.put(colName, valueArray);
            }
            finalObject.put(dimName, dimObject);
        }
        return finalObject;
    }
}


As to follow up with your observation, JSON follows JavaScript (or ECMAScript, as it should be called) reserved words and class is one of them.

EDIT:

While dabbling with javascript, it seems you can use reserve words within quotation marks, I have tested it as follows:

myObj = {"class" : "Analysis of Algorithms"}; // <--works
myObj = { class  : "Analysis of Algorithms"}; //  <--works
myObj = { class  : "class"}; // <--works
myObj = {"class" :  class }; // <--does not work.

As well it is interesting, I am still puzzled by the problem. With JSON I am using all my techniques with javascript, so I cannot produce the same results as you can.

I found the source file for JSONObject.java at this website


Edit: In your example, you're writing code in Java. I don't know what Java implementation of JSON you're using, but it's probably not strict. It's not meant to be a JavaScript interpreter or engine, so it's not preventing you from doing something you shouldn't do. That's why you can add the "class" key like you did -- the Java side is going to let you do that even though it's wrong. It's not checking to make sure you're not using keywords as identifiers. When that JSON gets interpreted by a web browser after it's left the Java world, you will have problems, because now that "class" word has a special meaning.

class is a reserved word. You should avoid using it as a variable name. See here for a list of reserved words.

Chrome's JavaScript console let me use it as an identifier. IE8 behaves differently. I can't use it in dot notation but I can use it with bracket notation. See a.class and a['class'] in the following.

>>var class = "1"
  "Expected identifier"
>>var a = "1"
undefined
>>a
"1"
>>class
  "Syntax error"
>>var a = {}
undefined
>>a["foo"] = "1"
"1"
>>a["class"] = "2"
"2"
>>a.class
  "Expected identifier"
>>a.foo
"1"
>>a['foo']
"1"
>>a['class']
"2"

The point is, don't use reserved words as identifiers. You probably won't get the results you expect.


the reason JSON uses { "double quotes":"around key/vals" } is for this exact reason - to escape reserved words.

that said, if you are getting valid JSON, there should be no problems, as any reserved words will be escaped by the "double quotes"...

I noticed you have a missing quote in this line:

finalObject#{"supplier:{"name":["sam"]}}

should be "supplier". is there anyway you could change that? or is it being auto generated?


I don't think that your minimal example correctly replicates the problem that you are experiencing.

Using the json java library from json.org, I ran this Java code:

public static void main(String[] args) throws JSONException {
    JSONObject dimObject=new JSONObject();
    dimObject.put("class",new JSONArray(new String[] {"A","B","c"}));
    dimObject.put("name", "sam");
    System.out.println("dimObject#"+dimObject.toString());
    JSONObject finalObject=new JSONObject();
    finalObject.put("supplier",dimObject);
    System.out.println("finalObject#"+finalObject.toString());
}

and the output was as expected:

dimObject#{"name":"sam","class":["A","B","c"]}
finalObject#{"supplier":{"name":"sam","class":["A","B","c"]}}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜