esahmo
esahmo

Reputation: 156

Remove extra white spaces from the json

In Java I have a json string and I want to remove the extra white spaces from it. I don't want to remove the space from the character in keys and values.

Actual JSON string

{ "Error" : "Invalid HTTP Method" , "ErrorCode" : "405" , "ErrorDesc" : "Method Not Allowed" } 

Required JSON

{"Error":"Invalid HTTP Method","ErrorCode":"405","ErrorDesc":"Method Not Allowed"}

Upvotes: 6

Views: 22448

Answers (6)

IntoVoid
IntoVoid

Reputation: 964

Ok this is probably my final answer to this post:

public static CharSequence removeWhitespaces(CharSequence json) {
    int len = json.length();

    StringBuilder builder = new StringBuilder(len);

    boolean escaped = false, quoted = false;
    for (int i = 0; i < len; i++) {
        char c = json.charAt(i);
        if (c == '\"') {
            if (!escaped) quoted = !quoted;
            else escaped = false;
        } else if (quoted && c == '\\') {
            escaped = true;
        }

        if (quoted || c != ' ') {
            builder.append(c);
        }
    }

    return builder;
}

Or if you want to assure that you got rid of all whitespace characters then use:

public static CharSequence removeWhitespaces(CharSequence json) {
    int len = json.length();

    StringBuilder builder = new StringBuilder(len);

    boolean escaped = false, quoted = false;
    for (int i = 0; i < len; i++) {
        char c = json.charAt(i);
        if (c == '\"') {
            if (!escaped) quoted = !quoted;
            else escaped = false;
        } else if (quoted && c == '\\') {
            escaped = true;
        }

        if (quoted || !Character.isWhitespace(c)) {
            builder.append(c);
        }
    }

    return builder;
}

This method is way more efficient than to first convert the string into a Json structure and back to a string, because that would be way to time consuming.

Telling the StringBuilder in advance which start capacity it should have also speeds up the process by a lot, if you have a long input String. (Capacity is not equals to length, meaning that even if you tell the StringBuilder eg. it should have a capacity of 100 it will still only have a length of the text you put into it)

And since StringBuilder implements CharSequence you can directly return the entire StringBuilder instead of converting it back to a String. But if you need a String and not a CharSequence, just call builder.toString(); at the end of this method and set the return type to String.

Upvotes: 0

Fabian Zimbalev
Fabian Zimbalev

Reputation: 553

I´d go with something like this:

public static void main(String[] args) {
    String json = "{ \"Error\": \"Inv\\\"alid HTTP Method\", \"ErrorCode\":\"405\",\"ErrorDesc\":\"Method Not Allowed\"}";

    System.out.println(removeWhitespaces(json));
}

public static String removeWhitespaces(String json) {

    boolean quoted = false;
    boolean escaped = false;
    String out = "";

    for(Character c : json.toCharArray()) {

        if(escaped) {
            out += c;
            escaped = false;
            continue;
        }

        if(c == '"') {
            quoted = !quoted;
        } else if(c == '\\') {
            escaped = true;
        }

        if(c == ' ' &! quoted) {
            continue;
        }

        out += c;

    }

    return out;

}

Testrun returns

{"Error":"Invalid HTTP Method","ErrorCode":"405","ErrorDesc":"Method Not Allowed"}

Upvotes: 3

Andrei Kovrov
Andrei Kovrov

Reputation: 2440

Don't forget about escaped quotes \"!

static String minimize(String input){
     StringBuffer strBuffer = new StringBuffer();    
     boolean qouteOpened = false;
     boolean wasEscaped = false;
     for(int i=0; i<input.length(); i++){
         char c = input.charAt(i);
         if (c == '\\') {
            wasEscaped = true;
         }
         if(c == '"') {
             qouteOpened = wasEscaped ? qouteOpened : !qouteOpened;
         }
         if(!qouteOpened && (c == ' ')){
             continue;
         }
         if (c != '\\') {
            wasEscaped = false;
         }
         strBuffer.append(c);
     }
     return strBuffer.toString();
}

Upvotes: 1

IntoVoid
IntoVoid

Reputation: 964

An even simpler an safer solution would be to use the Gson library (Only a few lines needed):

public static String simplify(String json) {
    Gson gson = new GsonBuilder().create();

    JsonElement el = JsonParser.parseString(json);
    return gson.toJson(el);
}

and you can even reverse the entire process (adding spaces) with Gson's pretty printing option:

public static String beautify(String json) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    JsonElement el = JsonParser.parseString(json);
    return gson.toJson(el);
}

Hope this will help you

You get the latest version from here: Gson Maven Repository

Upvotes: 12

IntoVoid
IntoVoid

Reputation: 964

What @Fabian Z said would probably work, but could be optimized (You don't need to convert the entire String to a char array first to iterate it and you should also use a StringBuilder):

public static String removeWhitespaces(String json) {
    boolean quoted = false;

    StringBuilder builder = new StringBuilder();

    int len = json.length();
    for (int i = 0; i < len; i++) {
        char c = json.charAt(i);
        if (c == '\"')
            quoted = !quoted;

        if (quoted || !Character.isWhitespace(c))
            builder.append(c);
    }

    return builder.toString();
}

Also when using

Character.isWhitespace(c)

it will also remove line breaks

Upvotes: 1

IntoVoid
IntoVoid

Reputation: 964

If you are using a JsonWriter to create that Json code, you could do

jsonWriter.setIndent("");

to remove all whitespaces in json code (Tested with Gson's Json Writer)

Upvotes: 0

Related Questions