diff --git a/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java b/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java index 7b3f7d14a4a..fd3ffc991b6 100644 --- a/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java +++ b/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java @@ -27,6 +27,7 @@ import java.io.InputStream; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; /** * @author Julien Viet @@ -34,22 +35,20 @@ public class DatabindCodec extends JacksonCodec { private static final ObjectMapper mapper = new ObjectMapper(); - private static final ObjectMapper prettyMapper = new ObjectMapper(); + private static final AtomicReference prettyMapper = new AtomicReference<>(); static { - initialize(); + initialize(mapper, false); } - private static void initialize() { + private static void initialize(ObjectMapper om, boolean prettyPrint) { // Non-standard JSON but we allow C style comments in our JSON - mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - - prettyMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - prettyMapper.configure(SerializationFeature.INDENT_OUTPUT, true); - + om.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + if (prettyPrint) { + om.configure(SerializationFeature.INDENT_OUTPUT, true); + } VertxModule module = new VertxModule(); - mapper.registerModule(module); - prettyMapper.registerModule(module); + om.registerModule(module); } /** @@ -65,7 +64,13 @@ public static ObjectMapper mapper() { */ @Deprecated public static ObjectMapper prettyMapper() { - return prettyMapper; + ObjectMapper pm = prettyMapper.get(); + if (pm != null) { + return pm; + } + pm = new ObjectMapper(); + initialize(pm, true); + return prettyMapper.compareAndSet(null, pm) ? pm : prettyMapper.get(); } @Override @@ -157,8 +162,13 @@ private static T fromParser(JsonParser parser, TypeReference type) throws @Override public String toString(Object object, boolean pretty) throws EncodeException { try { - ObjectMapper mapper = pretty ? DatabindCodec.prettyMapper : DatabindCodec.mapper; - return mapper.writeValueAsString(object); + String result; + if (pretty) { + result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); + } else { + result = mapper.writeValueAsString(object); + } + return result; } catch (Exception e) { throw new EncodeException("Failed to encode as JSON: " + e.getMessage()); } @@ -167,8 +177,13 @@ public String toString(Object object, boolean pretty) throws EncodeException { @Override public Buffer toBuffer(Object object, boolean pretty) throws EncodeException { try { - ObjectMapper mapper = pretty ? DatabindCodec.prettyMapper : DatabindCodec.mapper; - return Buffer.buffer(mapper.writeValueAsBytes(object)); + byte[] result; + if (pretty) { + result = mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(object); + } else { + result = mapper.writeValueAsBytes(object); + } + return Buffer.buffer(result); } catch (Exception e) { throw new EncodeException("Failed to encode as JSON: " + e.getMessage()); } diff --git a/src/test/java/io/vertx/core/json/JacksonDatabindTest.java b/src/test/java/io/vertx/core/json/JacksonDatabindTest.java index 8cf755f1fc6..16ff4154887 100644 --- a/src/test/java/io/vertx/core/json/JacksonDatabindTest.java +++ b/src/test/java/io/vertx/core/json/JacksonDatabindTest.java @@ -14,6 +14,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.SerializationFeature; +import io.vertx.core.ThreadingModel; import io.vertx.core.buffer.Buffer; import io.vertx.core.json.jackson.DatabindCodec; import io.vertx.core.json.jackson.JacksonCodec; @@ -108,4 +111,18 @@ private static class Pojo { @JsonProperty byte[] bytes; } + + @Test + public void testObjectMapperConfigAppliesToPrettyPrinting() { + ObjectMapper om = DatabindCodec.mapper(); + SerializationConfig sc = om.getSerializationConfig(); + assertNotNull(sc); + try { + om.setConfig(sc.with(SerializationFeature.WRITE_ENUMS_USING_INDEX)); + ThreadingModel vt = ThreadingModel.VIRTUAL_THREAD; + assertEquals(Json.encode(vt), Json.encodePrettily(vt)); + } finally { + om.setConfig(sc); + } + } }