mongodbmongo-java-driver

Java BsonArray to json string


How can I convert a Java (/Scala) BsonArray to a json string?

If I have

val array = new BsonArray()
array.add(new BsonInt32(1))
array.add(new BsonInt32(2))

it would be nice if "array.toJson" gave me

"[1, 2]"

But BsonArray has no toJson method. So what could I do instead?

The real content of my array is more complex (nested documents) and I need to pretty-print it with indentations.

When I need to convert a BsonDocument I can call its toJson method

val doc = new BsonDocument()
// ..populate doc..
val pretty = JsonWriterSettings.builder().indent(true).build()
doc.toJson(pretty)

Solution

  • This can be done in a hacky way by creating a temporary BsonDocument object with the BsonArray object as its value, converting the BsonDocument to JSON and then extracting out the part corresponding to the BsonArray from the output JSON string. Something like the below:

    public static String toJson(BsonArray bsonArray) {
        BsonDocument temp = new BsonDocument("x", bsonArray);
        String json = temp.toJson(JsonWriterSettings.builder().indent(true).build());
    
        return json.substring(9, json.length() - 1).stripTrailing();
    }
    

    You could also build the JSON yourself using a method like the below, but it might end up being a little too long and complicated(even before pretty print) if you need to handle all BsonValue types.

    public static String toJson(BsonArray bsonArray) {
        String json = null;
    
        if (null != bsonArray) {
            StringBuilder jsonBuilder = new StringBuilder("[");
    
            for (int index = 0; index < bsonArray.size(); index++) {
                BsonValue value = bsonArray.get(index);
    
                if (value instanceof BsonInt32) {
                    jsonBuilder.append(((BsonInt32) value).getValue());
                } else if (value instanceof BsonDocument) {
                    jsonBuilder.append(((BsonDocument) value).toJson());
                } else if (value instanceof BsonArray) {
                    jsonBuilder.append(toJson((BsonArray)value));
                } else if (value instanceof BsonBoolean) {
                    jsonBuilder.append(((BsonBoolean) value).getValue());
                } else if (value instanceof BsonString) {
                    jsonBuilder.append('"');
                    jsonBuilder.append(((BsonString) value).getValue());
                    jsonBuilder.append('"');
                }
                // TODO Handle other required BsonValue data types like BsonInt64, BsonDouble, BsonTimestamp, etc
    
                if (index != bsonArray.size() - 1) {
                    jsonBuilder.append(", ");
                }
            }
    
            jsonBuilder.append(']');
            json = jsonBuilder.toString();
        }
    
        return json;
    }