Java Simple json not replacing the value of a attribute
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());
You have the object inside you json objectYou need to get the inner data object and modify itjsonObj.get("data").put("name", "abc")
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 parsed
document 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(""); }