2

As the tital states above I am trying to replace the value for "name" to "abc" but that does not seem to overwrite it as it's the same value after replacing it using the Simple Json java code.

This is my java code:

    String jsonString = 
    "{"
        + "\"data\":"
        + "["
            + "{"
                + "\"jazz\":\"black\","
                + "\"name\":\"white\","
                + "\"given\":\"red\","
                + "\"sam\":\"blue\","
                + "\"mail\":\"yellow\","
                + "\"member\":\"green\","
                + "\"department\":\"green\","
                + "\"title\":\"green\""
            + "}"
        + "]"
    + "}";
    JSONParser parser = new JSONParser();
    JSONObject jsonObj = (JSONObject) parser.parse(jsonString);
    JSONObject newJSON = new JSONObject();

    jsonObj.remove("name");
    jsonObj.put("name", "abc");

As I said, the code above seems to not do anything for the "name" attribute that's already in the json structure. The output for the above looks like this:

{
    "data": [
        {
            "given": "red",
            "mail": "yellow",
            "jazz": "black",
            "name": "white",
            "member": "green",
            "department": "green",
            "title": "green",
            "sam": "blue"
        }
    ],
    "name": "abc"
}

What the output should look like:

{
    "data": [
        {
            "given": "red",
            "mail": "yellow",
            "jazz": "black",
            "name": "abc",
            "member": "green",
            "department": "green",
            "title": "green",
            "sam": "blue"
        }
    ]
}

Any idea as to why its not changing it?

UPDATE 1

enter image description here

StealthRT
  • 10,108
  • 40
  • 183
  • 342

3 Answers3

2

You have the object inside you json object You need to get the inner data object and modify it jsonObj.get("data").put("name", "abc")

asfmlr
  • 199
  • 11
  • Thanks for the reply. However, i do not seem to have a "put" option? Please see the update to the OP. – StealthRT Sep 23 '19 at 17:21
  • you right, JsonObject.get returns Object you should cast it to JsonObject ((JSONObject)jsonObj.get("data")).put("name", "abc") @StealthRT – asfmlr Sep 23 '19 at 18:23
  • Error **org.json.simple.JSONArray incompatible with org.json.simple.JSONObject** – StealthRT Sep 23 '19 at 18:28
  • i didn't notice that data is an array so you should cast to array and get the relevant item in the array tehn perfrom the put: ((JSONObject)((JSONArray)jsonObj).get(0)).get("data")).put("name", "abc") – asfmlr Sep 23 '19 at 18:32
2

this worked for me:

JSONArray jsonArray = (JSONArray)jsonObj.get("data");
    JSONObject jsonObject = ((JSONObject)(jsonArray).get(0));
    jsonObject.put("name", "abc");
    System.out.println(jsonObj.toJSONString());
asfmlr
  • 199
  • 11
1

Time to time you can be faced with situations where would be perfect to replace some values in flexible way. So I'd like to show this additional approach using json-path dependency.

Specify path collection to replace real data, for example:

import static com.google.common.collect.Lists.newArrayList;

...

    private static final List<String> PATHS_TO_REPLACE = newArrayList(
            "$.email",
            "$.colleagues.[*].email",
            "$.other.required.pathmask"
    );

And most important code part:

    public String maskSensitiveData(String asJson) {
        DocumentContext parsed = JsonPath.parse(asJson);
        PATHS_TO_REPLACE.forEach(path -> parsed.set(path, "***starred***"));
        return parsed.jsonString();
    }

To avoid of com.jayway.jsonpath.PathNotFoundException if you sure they have to be suppressed, you can use special configuration:

    private static final Configuration CONFIGURATION = Configuration
            .builder()
            .options(Option.SUPPRESS_EXCEPTIONS)
            .build();

and parseddocument should be given in updated way:

    DocumentContext parsed = JsonPath.using(CONFIGURATION).parse(asJson);

To play with code I'd recommend try prepared test for correspond service.

P.S.

If you want calculate stars for setting value (or hide only part of data) in dynamic way it also can be handled. To keep it simple for data arrays, please pay your attention on map method of the same object. Correspond example also added to the service:

    public String flexibleMaskingSensitiveData(String asJson) {
        DocumentContext parsed = JsonPath.using(CONFIGURATION).parse(asJson);
        PATHS_TO_REPLACE.forEach(path -> parsed.map(path,
                (currentValue, conf) -> starringCurrentValue(currentValue)));
        return parsed.jsonString();
    }

    private Object starringCurrentValue(Object currentValue) {
        return ofNullable(currentValue)
                .filter(String.class::isInstance)
                .map(String.class::cast)
                .map(String::length)
                .map(times -> StringUtils.repeat('*', times))
                .orElse("");
    }
Sergii
  • 7,044
  • 14
  • 58
  • 116