10

I want to rename the keys of a JSON object using Java.

My input JSON is:

{  
    "serviceCentreLon":73.003742,
    "type":"servicecentre",
    "serviceCentreLat":19.121737,
    "clientId":"NMMC01" 
}

I want to change it to:

{  
    "longitude":73.003742,
    "type":"servicecentre",
    "latitude":19.121737,
    "clientId":"NMMC01" 
}

i.e. I want to rename "serviceCentreLon" to "longitude" and "serviceCentreLat" to "latitude". I am using the JSONObject type in my code.

0

8 Answers 8

21

Assuming you're using the json.org library: once you have a JSONObject, why not just do this?

obj.put("longitude", obj.get("serviceCentreLon"));
obj.remove("serviceCentreLon");
obj.put("latitude", obj.get("serviceCentreLat"));
obj.remove("serviceCentreLat");

You could create a rename method that does this (then call it twice), but that's probably overkill if these are the only fields you're renaming.

Sign up to request clarification or add additional context in comments.

Comments

3
String data= json.toString();
data=data.replace("serviceCentreLon","longitude");
data=data.replace("serviceCentreLat","latitude");

convert back to json object

Comments

3

I'm not sure whether I get your question right, but shouldn't the following work?

You could use a regular expression to replace the keys, for example:

String str = myJsonObject.toString();
str = str.replace(/"serviceCentreLon":/g, '"longitude":');
str = str.replace(/"serviceCentreLat":/g, '"latitude":');

It's not as "clean", but it might get the job done fast.

2 Comments

How do we replace both key and value, lets say "serviceCentreLon":73.003742 to "longitude":"80.456", is there a way to do this?
your code snippet doesn't even compile by javac
3

To build on Danyal Sandeelo's approach, instead of:

data=data.replace("serviceCentreLon","longitude");

use

data=data.replace("\"serviceCentreLon\":","\"longitude\":");

This method explicitly matches the json key syntax, and avoids obscure errors where the key value is present as valid data elsewhere in the json string.

1 Comment

"foo\"serviceCentreLon": "bar" becomes "foo\"longitude": "bar"
1

The best way to approach the problem is to parse the JSON data and then replace the key. A number of parsers are available - google gson, Jackson serializer de-serializers, org.json.me are a few such java libraries to handle JSON data.

http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/

is a good way to deal with it if you have a pretty generic and relatively huge JSON data. Of course, you have to spend time in learning the library and how to use it well.

http://www.baeldung.com/jackson-map is another such parser.

https://stleary.github.io/JSON-java/ is the simplest one especially if you don't want any serious serialization or deserialization

Comments

0

Have an object that maps to this object data structure.

Use GSON parser or Jackson parser to convert this json into POJO.

Then map this object to another Java Object with required configuration

Convert that POJO back to json using the same GSON parsers.


refer this for further reference

http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/

Comments

0

I faced this problem during my work so I've made a useful Utils class and I want to share it with you.

package net.so.json;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.json.JSONObject;

public class Utils {
    
    /**
     * replace json object keys with the new one
     * @param jsonString represents json object as string
     * @param oldJsonKeyNewJsonKeyMap map its key old json key & its value new key name if nested json key you have traverse
     * through it using . example (root.coutry, count) "root.country" means country is a key inside root object
     * and "count" is the new name for country key
     * Also, if the value for the map key is null, this key will be removed from json
     */
    public static void replaceJsonKeys(final JSONObject jsonObject, final Map<String, String> oldJsonKeyNewJsonKeyMap) {
        if (null == jsonObject || null == oldJsonKeyNewJsonKeyMap) {
            return;
        }
        
        
        // sort the old json keys descending because we want to replace the name of the inner most key first, then 
        // the outer one
        final List<String> oldJsonKeys = oldJsonKeyNewJsonKeyMap.keySet().stream().sorted((k2, k1) -> k1.compareTo(k2)).collect(Collectors.toList());
        
        oldJsonKeys.forEach(k -> {
            // split old key, remember old key is something like than root.country
            final String[] oldJsonKeyArr = k.split("\\.");
            
            final int N = oldJsonKeyArr.length;
            
            
            // get the object hold that old key
            JSONObject tempJsonObject = jsonObject;
            for (int i = 0; i < N - 1; i++)
                tempJsonObject = tempJsonObject.getJSONObject(oldJsonKeyArr[i]);
            
            final String newJsonKey = oldJsonKeyNewJsonKeyMap.get(k);
            
            // if value of the map for a give old json key is null, we just remove that key from json object
            if (!"null".equalsIgnoreCase(newJsonKey))
                tempJsonObject.put(newJsonKey, tempJsonObject.get(oldJsonKeyArr[N - 1]));
            
            // remove the old json key
            tempJsonObject.remove(oldJsonKeyArr[N - 1]);
        
        });
        
            
        
    }

}

you can test this class by running App

package net.so.json;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

public class App {
    
    public static void main(String[] args) {
        final String jsonString = "{\"root\":{\"country\": \"test-country\", \"city\": \"test-city\"}}";
        final JSONObject jsonObject = new JSONObject(jsonString);
        
        System.out.println("json before replacement: " + jsonObject);
        /* will get >>
           {
              "root": {
                  "country": "test-country",
                  "city": "test-city"
               }
            }
        */
        
        // construct map of key replacements
        final Map<String, String> map = new HashMap<>();
        map.put("root", "root2");
        map.put("root.country", "count");
        map.put("root.city", "null"); // null as a value means we want to remove this key
        
        
        Utils.replaceJsonKeys(jsonObject, map);
        
        System.out.println("json after replacement: " + jsonObject);
        /* will get >>    
          {
             "root2": {
               "count": "test-country"
             }
          }
        */
                
    }

}

Comments

0

I ran into a scenario where I wanted to remove a hyphen from an unknown number of keys in a nested object.

So this:

{
    "-frame": {
        "-shape": {
            "-rectangle": {
                "-version": "1"
            }
        },
        "-path": {
            "-geometry": {
                "-start": {
                    "-x": "26.883513064453602",
                    "-y": "31.986310940359715"
                }
            },
            "-id": 1,
            "-type": "dribble",
            "-name": "MultiSegmentStencil",
            "-arrowhead": "0"
        }
    }
}

Would be this:

{
    "frame": {
        "shape": {
            "rectangle": {
                "version": "1"
            }
        },
        "path": {
            "geometry": {
                "start": {
                    "x": "26.883513064453602",
                    "y": "31.986310940359715"
                }
            },
            "id": 1,
            "type": "dribble",
            "name": "MultiSegmentStencil",
            "arrowhead": "0"
        }
    }
}

A recursive method(kotlin).. with a list did the trick via Jackson

fun normalizeKeys(tree: JsonNode, fieldsToBeRemoved: MutableList<String>) {

        val  node = tree as ContainerNode<*>

        val firstClassFields = node.fields()
        while(firstClassFields.hasNext()) {
            val field = firstClassFields.next()
            if(field.key.substring(0,1) == "-") {
                fieldsToBeRemoved.add(field.key)
            }
            if(field.value.isContainerNode) {
                normalizeKeys(field.value, fieldsToBeRemoved)
            }
        }

        fieldsToBeRemoved.forEach {
            val fieldByKey: MutableMap.MutableEntry<String, JsonNode>? = getFieldByKey(tree, it)
            if(fieldByKey != null) {
                (tree as ObjectNode)[fieldByKey!!.key.replaceFirst("-","")] = fieldByKey.value
                (tree as ObjectNode).remove(fieldByKey!!.key)
                }
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.