Remove duplicate key and value from json in java - java

I am mapping Object (i don't have control over) to jsonString, after mapping I get duplicate key-value pairs in the JSON,
example
{
"id":"123",
"email":"someEmail#gmail.com",
"UserName":"someOne",
"EMAIL":"someEmail#gmail.com"
}
the duplicate is exactly the same except that it is in uppercase letters.
I am trying to get a jsonInString format without the duplication. Something like this:
{
"id":"123",
"email":"someEmail#gmail.com",
"UserName":"someOne"
}
I have tried
String jsonInStringWithOutDuplication=mapper.enable(
JsonParser.Feature.STRICT_DUPLICATE_DETECTION).writeValueAsString(users);
with no luck, any suggestions?

If you don't find a way to configure the ObjectMapper to filter out duplicate attributes, you can serialize the problematic object to JSON, then serialize the JSON to a Map object, merge duplicate attributes and serialize it to JSON again:
Map<String, String> objectWithDuplicates = new HashMap<>();
map.put("name", "MyName");
map.put("email", "em#ail");
map.put("EMAIL", "em#ail");
ObjectMapper mapper = new ObjectMapper();
String jsonWithDuplicates = mapper.writeValueAsString(objectWithDuplicates);
Map<String, Object> attributesWithDuplicates = mapper
.readValue(jsonWithDuplicates, Map.class);
Map<String, Object> withoutDuplicates = new HashMap<>();
attributesWithDuplicates.forEach((key, value) -> {
if (! withoutDuplicates.containsKey(key.toLowerCase())) {
withoutDuplicates.put(key.toLowerCase(), value);
}
});
String json = mapper.writeValueAsString(withoutDuplicates);

Jackson's ObjectMapper has a feature that puts the same keys into an array. Isn't it something that could help you?
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new GuavaModule());
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Multimap resultAsMultimap = mapper.readValue(json, Multimap.class);
System.out.println(resultAsMultimap);

Related

How to map JSON to Java HashMap

I have a JSON like this: [{key:key1, value:value1}, {key:key2, value:value2}, ..., {key:keyn, value:valuen}]
and I need a HashMap in Java from that json like: {key1:value1, key2:value2, ..., keyn:valuen}
Is there a simple way to have it converted like this? I'm trying with Jackson but don't know how to specify key and value keywords.
It is very simple:
https://stackoverflow.com/a/24012023/7137584
I would recommend using Jackson library:
import com.fasterxml.jackson.databind.ObjectMapper;
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<>() {};
Map<String, Object> mapping = new ObjectMapper().readValue(jsonStr, typeRef);
The input JSON describes an array/list of map entries where each entry is a POJO:
#Data
class Entry {
private String key;
private String value; // the type of value may be Object
}
Here #Data is a Lombok annotation which provides getters, setters, toString, etc.
So, at first a list of map entries is read, which is converted then to the map:
String json = "[{\"key\":\"key1\", \"value\":\"value1\"}, {\"key\":\"key2\", \"value\":\"value2\"}, {\"key\":\"keyN\", \"value\":\"valueN\"}]";
// step 1: read raw list of entries
List<Entry> input = mapper.readValue(json, new TypeReference<List<Entry>>() {});
// step 2: convert to map
Map<String, String> mapRead = input.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
System.out.println(mapRead);
Output:
{key1=value1, key2=value2, keyN=valueN}
Here's a solution using the JSON-P api.
import javax.json.*;
var str = "[{\"key\":\"key1\", \"value\":\"value1\"}, {\"key\":\"key2\", \"value\":\"value2\"}, {\"key\":\"keyN\", \"value\":\"valueN\"}]";
JsonReader reader = Json.createReader(new StringReader(str));
JsonArray jarr = reader.readArray();
Map<String,String> map = new HashMap<>();
for(JsonValue jv : jarr) {
JsonObject jo = (JsonObject)jv;
map.put(jo.getString("key"), jo.getString("value") );
}
System.out.println(map);
I am using a JsonReader to convert the String to a JsonArray object.
Each entry of this JsonArray is a JsonObject like {key: keyX, value: valueX}.
I get the values corresponding to 'key' and 'value' and add them to a HashMap using a for loop.

Merge JSON Tree Jackson

I want to merge two JSON trees with jackson.
JSONTree1:
{"test":{"test1":"test1"}}
JSONTree2:
{"test":{"test2":"test2"}}
Output:
{"test":{"test1":"test1", "test2":"test2"}}
Is there an easy method in jackson which does this? I cant find one. Thanks for your help.
You can achieve it with jackson as below,
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> json1 = mapper.readValue("{\"test\":{\"test1\":\"test1\"}}", Map.class);
Map<String, Object> json2 = mapper.readValue("{\"test\":{\"test2\":\"test2\"}}", Map.class);
Map result = new HashMap<>();
json1.forEach((k,v)->json2.merge(k, v, (v1, v2)->
{
Map map = new HashMap<>();
map.putAll((Map) v1);
map.putAll((Map) v2);
result.put(k, map);
return v2;
} ));
String resultJson = new ObjectMapper().writeValueAsString(result);
System.out.println(resultJson);
Result:
{"test":{"test1":"test1","test2":"test2"}}

Need to deserialize this JSON with Jackson - [{}, {}, {}] - What Jackson annotation to use for JSON array?

I’m currently writing Java client code that gets a JSON response from a rest service. For my JSON response, I need to deserialize it to a pojo. If the JSON’s outer most wrappers are square brackets that enclose a list of objects, what Jackson annotation can I use to load it to an array or ArrayList?
The JSON looks like this:
[{"key1": "val1"}, {"key2": "val2"}, {"key3": "val3"}]
Jackson can unmarshall json directly to your object, vise-versa.
public void givenJsonArray_whenDeserializingAsArray_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
List<MyDto> listOfDtos = Lists.newArrayList(
new MyDto("a", 1, true), new MyDto("bc", 3, false));
String jsonArray = mapper.writeValueAsString(listOfDtos);
// [{"stringValue":"a","intValue":1,"booleanValue":true},
// {"stringValue":"bc","intValue":3,"booleanValue":false}]
MyDto[] asArray = mapper.readValue(jsonArray, MyDto[].class);
assertThat(asArray[0], instanceOf(MyDto.class));
}
source:https://www.baeldung.com/jackson-collection-array
you can try this
String json = "[{\"key1\": \"val1\"}, {\"key2\": \"val2\"}, {\"key3\": \"val3\"}]";
ObjectMapper mapper = new ObjectMapper();
ArrayList<Map<String,String>> list = mapper.readValue(json, Object.class);
for (Map map : list)
for (Object key :map.keySet())
System.out.println("key: "+key.toString()+" value:"+map.get(key));
//result
//key: key1 value:val1
//key: key2 value:val2
//key: key3 value:val3

Java - Convert complexe List#toString to a List

I use this list:
List<HashMap<Map<String, Object>, Map<String, Object>>>
And I need to save it to a text file.
So with the List#toString method, I obtain a text like that:
[{{key=value, key=value, key=value}={key=value, key=value}}, {{key=value, key=value, key=value}={key=value, key=value}}, {{key=value, key=value, key=value}={key=value, key=value}}]
How can I convert it back to a List?
Thanks!
You are better off using a format like JSON or YAML. Usng toString() means there is too many corner cases like a = { } or , appearing in a key or value.
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map1=new HashMap<>();
map1.put("key","value");
map1.put("key1","value");
map1.put("key2","value");
map1.put("key3","value");
HashMap<Map<String, Object>, Map<String, Object>> hash=new HashMap<>();
List<HashMap<Map<String, Object>, Map<String, Object>>> lists=new ArrayList<>();
hash.put(map1, map1);
lists.add(hash);
System.out.println(mapper.writeValueAsString(lists));
The toString() method produces a format that is intended for logging and debugging, not for serialization and deserialization.
I recommend to convert your object into json format (other formats like xml can work just as well) and use a json library such as "Gson" for conversions.
Example how you can convert your object into a json string:
Gson gson = new Gson();
String json = gson.toJson(myObject);
Example how you can convert the json string back into an object, see:
creating Hashmap from a JSON String
Update: Here's a complete example of the first part:
List<HashMap<Map<String, Object>, Map<String, Object>>> myObject = new ArrayList<>();
HashMap<Map<String, Object>, Map<String, Object>> hashMap1 = new HashMap<>();
myObject.add(hashMap1);
Map<String, Object> key1 = new HashMap<>();
key1.put("key1", "keyValue1");
Map<String, Object> value1 = new HashMap<>();
value1.put("value1", "valueValue1");
hashMap1.put(key1, value1);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String json = gson.toJson(myObject);
System.out.println(json);
This example prints:
[{"{key1=keyValue1}":{"value1":"valueValue1"}}]
Update2 Use Pair (from apache commons lang3) instead of HashMap. That makes a lot more sense.
List<Pair<Map<String, Object>, Map<String, Object>>> myObject = new ArrayList<>();
MutablePair<Map<String, Object>, Map<String, Object>> pair1 = new MutablePair<>();
myObject.add(pair1);
Map<String, Object> key1 = new HashMap<>();
key1.put("key1", "keyValue1");
Map<String, Object> value1 = new HashMap<>();
value1.put("value1", "valueValue1");
pair1.setLeft(key1);
pair1.setRight(value1);
Gson gson = new Gson();
String json = gson.toJson(myObject);
System.out.println(json);
Prints:
[{"left":{"key1":"keyValue1"},"right":{"value1":"valueValue1"}}]

Simple Java Json to Array

I'm stuck on something silly I'd appriciate some help with,
I'm getting this string via a stringified object in javascript:
{"63F67024-6FE1-D1B9-41D2-61156F11089A":0,"7cc8732e-d532-463e-9b5e-38fe14664b9e":1,"7CC40FFC-7BED-82DF-41C3-78C2BE8CD901":2,"f7344b33-860a-4934-b1f8-044b80a7b894":3,"31f65628-12b1-4363-848d-2bce07b8ac30":4,"7CF2DCA9-7BEC-8566-41A2-4898E5C110BC":5,"7D1C42ED-7BED-82FE-41D2-5045E9F0C13F":6,"D4EC2E5B-D807-2F30-41EA-6A4D9278BE81":7,"91ACF8F7-9516-F12F-41C1-BF57E6F223BE":8,"28d65730-9da0-457b-9d25-0f33628c0e5c":9,"57D44260-6D6D-E0E0-4171-71080149751C":10}
What's the cleanest, simplest way to convert this into an array of objects?
I've started doing something ugly by just removing the unwanted characters and doing something like this:
List<String> list = new ArrayList<String>(Arrays.asList(value.split(",")));
for(String s : list)
System.out.println(s);
But I'm sure there is a cleaner, simpler way ideally with GSON
Your JSON string looks like a simple list of key/value pairs. How about converting it to a Map
public static void jsonToMap(String t) throws JSONException {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject jObject = new JSONObject(t);
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ){
String key = (String)keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
System.out.println("json : "+jObject);
System.out.println("map : "+map);
}
Hope it helps.
jackson having ObjectMapper class which also doing this but it map the with the object and key name and object field name should be same for mapping code will be
import following package
org.codehaus.jackson.map.ObjectMapper;
call will be
ObjectMapper objectMapper = new ObjectMapper();
Yourclass classObj = objectMapper
.readValue(jsonasString,Yourclass.class);

Categories

Resources