Index: src/org/openstreetmap/josm/io/GeoJSONReader.java
===================================================================
--- src/org/openstreetmap/josm/io/GeoJSONReader.java	(revision 16928)
+++ src/org/openstreetmap/josm/io/GeoJSONReader.java	(working copy)
@@ -335,12 +343,12 @@

                     if (value instanceof JsonString) {
                         tags.put(stringJsonValueEntry.getKey(), ((JsonString) value).getString());
-                    } else if (value instanceof JsonObject) {
-                        Logging.warn(
-                            "The GeoJSON contains an object with property '" + stringJsonValueEntry.getKey()
-                                + "' whose value has the unsupported type '" + value.getClass().getSimpleName()
-                                + "'. That key-value pair is ignored!"
-                        );
+                    } else if (value instanceof JsonObject || value instanceof JsonArray) {
+                        /* When writing back to file, "{" and "}" are used to
+                         * determine that it should be interpreted  as a json
+                         * object or array. They are stored in GeoJSONWriter as variables. */
+                        tags.put(stringJsonValueEntry.getKey(), GeoJSONWriter.JSON_VALUE_START_MARKER + value.toString() +
+                                GeoJSONWriter.JSON_VALUE_END_MARKER);
                     } else if (value.getValueType() != JsonValue.ValueType.NULL) {
                         tags.put(stringJsonValueEntry.getKey(), value.toString());
                     }
Index: src/org/openstreetmap/josm/io/GeoJSONWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 16928)
+++ src/org/openstreetmap/josm/io/GeoJSONWriter.java	(working copy)
@@ -1,6 +1,7 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.io;

+import java.io.StringReader;
 import java.io.StringWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -21,6 +22,8 @@
 import javax.json.JsonValue;
 import javax.json.JsonWriter;
 import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;

 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -54,6 +57,19 @@
     private static final Set<Way> processedMultipolygonWays = new HashSet<>();

     /**
+     * This is used to determine that a tag should be interpreted as a json
+     * object or array. The tag should have both {@link #JSON_VALUE_END_MARKER}
+     * and {@link #JSON_VALUE_START_MARKER}.
+     */
+    static final String JSON_VALUE_START_MARKER = "{";
+    /**
+     * This is used to determine that a tag should be interpreted as a json
+     * object or array. The tag should have both {@link #JSON_VALUE_END_MARKER}
+     * and {@link #JSON_VALUE_START_MARKER}.
+     */
+    static final String JSON_VALUE_END_MARKER = "}";
+
+    /**
      * Constructs a new {@code GeoJSONWriter}.
      * @param ds The OSM data set to save
      * @since 12806
@@ -182,7 +198,7 @@
         // Properties
         final JsonObjectBuilder propObj = Json.createObjectBuilder();
         for (Entry<String, String> t : p.getKeys().entrySet()) {
-            propObj.add(t.getKey(), t.getValue());
+            propObj.add(t.getKey(), convertValueToJson(t.getValue()));
         }
         final JsonObject prop = propObj.build();

@@ -200,6 +216,20 @@
         }
     }

+    private static JsonValue convertValueToJson(String value) {
+        if (value.startsWith(JSON_VALUE_START_MARKER) && value.endsWith(JSON_VALUE_END_MARKER)) {
+            // Trim the markers
+            String toParse = value.substring(1, value.length() - 2);
+            try (JsonParser parser = Json.createParser(new StringReader(toParse))) {
+                if (parser.hasNext() && parser.next() != null)
+                    return parser.getValue();
+            } catch (JsonParsingException e) {
+                Logging.trace(e);
+            }
+        }
+        return Json.createValue(value);
+    }
+
     protected void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
         if (ds != null) {
             Iterator<Bounds> it = ds.getDataSourceBounds().iterator();
