john
john

Reputation: 11689

How to create a new JSON string by modifying few fields in it using Regular Expressions?

I am working with JSON and I will have JSON like this - I called it as originalJsonResponse. All the below json are same, it's just that user_id and uid field might have these types of variations -

{ "user_id": { "long": 159002376 }, "filter": { "string": "hello" } }
{ "user_id": { "string": "159002376" }, "filter": { "string": "hello" } }
{ "user_id": "159002376" , "filter": { "string": "hello" } }
{ "user_id": 159002376 , "filter": { "string": "hello" } }
{ "user_id": null, "filter": { "string": "hello" } }

{ "uid": { "long": 159002376 }, "filter": { "string": "hello" } }
{ "uid": { "string": "159002376" }, "filter": { "string": "hello" } }
{ "uid": "159002376" , "filter": { "string": "hello" } }
{ "uid": 159002376 , "filter": { "string": "hello" } }
{ "uid": null, "filter": { "string": "hello" } }

{ "filter": { "string": "hello" } }

Now I need to extract user_id or uid field from the JSON (if it is present) and if the value of those fields are not null, then change the value of those fields to a new user id and then construct another new json with the new user id in it.

As an example, I will have newUserId as 1267818821, then my new json should look like this and new json should have the same structure as old json -

{ "user_id": { "long": 1267818821 }, "filter": { "string": "hello" } }
{ "user_id": { "string": "1267818821" }, "filter": { "string": "hello" } }
{ "user_id": "1267818821" , "filter": { "string": "hello" } }
{ "user_id": 1267818821 , "filter": { "string": "hello" } }
{ "user_id": null, "filter": { "string": "hello" } }

{ "uid": { "long": 1267818821 }, "filter": { "string": "hello" } }
{ "uid": { "string": "1267818821" }, "filter": { "string": "hello" } }
{ "uid": "1267818821" , "filter": { "string": "hello" } }
{ "uid": 1267818821 , "filter": { "string": "hello" } }
{ "uid": null, "filter": { "string": "hello" } }

{ "filter": { "string": "hello" } }

What is the best way to do this obfuscation of user_id and uid field?

Below is my method in which I want to do the obfuscation -

private static String obfuscateJson(String originalJsonResponse, String oldUserId, String newUserId) {
    // here oldUserId is 159002376 and newUserId is 1267818821

    // not sure what I should do here to construct a new json with newUserId

    String newJsonResponse = // make a new json here
    return newJsonResponse;
}

I cannot use replaceAll method here (that's what I have started with and realize it will not work) since I might have another json with different fields and those fields might have oldUserId number in it so I don't want to replace those. Is there any better way of doing this?

// not a good solution
String newJsonResponse = originalJsonResponse.replaceAll(String.valueOf(oldUserId), String.valueOf(newUserId));

I want to make this more generic so that in future if I want to replace some other fields instead of user_id and uid field, then I should be able to do it easily.

Upvotes: 0

Views: 759

Answers (2)

Ravi K Thapliyal
Ravi K Thapliyal

Reputation: 51711

Since you've shared all the possible input JSON string patterns for the user_id field here, I would like to present again my JSON parser solution proposed before but updated to handle your different JSON types now.

public static void main(String[] args) {
    String[][] jsonInputs = new String[6][2];

    jsonInputs[0][0] = "Long-Object";
    jsonInputs[0][1] = "{ \"user_id\":{\"long\":876},\"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";

    jsonInputs[1][0] = "String-Object";
    jsonInputs[1][1] = "{ \"user_id\":{\"string\": \"876\"},\"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";

    jsonInputs[2][0] = "String";
    jsonInputs[2][1] = "{ \"user_id\": \"1267818821\" , \"filter\": { \"string\": \"hello\" } }";

    jsonInputs[3][0] = "Long";
    jsonInputs[3][1] = "{ \"user_id\": 1267818821 , \"filter\": { \"string\": \"hello\" } }";

    jsonInputs[4][0] = "Null";
    jsonInputs[4][1] = "{ \"user_id\": null , \"filter\": { \"string\": \"hello\" } }";

    jsonInputs[5][0] = "Not-Present";
    jsonInputs[5][1] = "{ \"filter\": { \"string\": \"hello\" } }";

    for (String[] json : jsonInputs) {
        System.out.println(json[0]);
        System.out.println(changeJsonString(json[1], "54321"));
        System.out.println();
    }
}

private static String changeJsonString(String originalResponse, String newId) {
    try {
        JSONObject root = new JSONObject(originalResponse);
        if (!root.isNull("user_id")) {
            Object userObj = root.get("user_id");
            if (userObj instanceof JSONObject) {
                JSONObject userId = (JSONObject) userObj;
                if (userId.has("long")) {
                    userId.put("long", Long.parseLong(newId));
                } else {
                    userId.put("string", newId);
                }
            } else if (userObj instanceof Number) {
                root.put("user_id", Long.parseLong(newId));
            } else {
                root.put("user_id", newId);
            }
        }
        return root.toString();
    } catch (JSONException e) {
        e.printStackTrace();
        return null;
    }
}

Output :

Long-Object
{"user_id":{"long":54321},"client_id":{"int":0},"affinity":[{"scoring":{"float":0.19},"try":{"long":55787693}},{"scoring":{"float":0.0114},"try":{"long":1763}}]}

String-Object
{"user_id":{"string":"54321"},"client_id":{"int":0},"affinity":[{"scoring":{"float":0.19},"try":{"long":55787693}},{"scoring":{"float":0.0114},"try":{"long":1763}}]}

String
{"filter":{"string":"hello"},"user_id":"54321"}

Long
{"filter":{"string":"hello"},"user_id":54321}

Null
{"filter":{"string":"hello"},"user_id":null}

Not-Present
{"filter":{"string":"hello"}}

Upvotes: 1

khampson
khampson

Reputation: 15306

This is not a use case that lends itself to regular expressions.

For this type of thing a JSON Processor is definitely what you would want to use. This way you can deserialize the incoming JSON into a class you define, alter the values and structure as needed, and then serialize it back into the outgoing JSON response.

I use and would recommend Jackson, but you could use GSON also if you wanted. There's also a Jackson quickstart tutorial.

You could specify that only non-null values get serialized by the annotation @JsonInclude(Include.NON_NULL), so that if, say, the JSON had user_id but not uid, the null uid would not get serialized.

To handle the complexity of the different variations within a particular property (e.g. user_id as a long or a string or a nested hash of either type), it would probably be best to write custom serializers and deserializers. GSON has these as well.

Upvotes: 0

Related Questions