diff --git a/spring-protobuf/pom.xml b/spring-protobuf/pom.xml
index 44a83803bd..e231f20b4d 100644
--- a/spring-protobuf/pom.xml
+++ b/spring-protobuf/pom.xml
@@ -20,6 +20,11 @@
protobuf-java
${protobuf-java.version}
+
+ com.google.protobuf
+ protobuf-java-util
+ ${protobuf-java.version}
+
com.googlecode.protobuf-java-format
protobuf-java-format
diff --git a/spring-protobuf/src/main/java/com/baeldung/protobuf/convert/ProtobuffUtil.java b/spring-protobuf/src/main/java/com/baeldung/protobuf/convert/ProtobuffUtil.java
new file mode 100644
index 0000000000..22481a776e
--- /dev/null
+++ b/spring-protobuf/src/main/java/com/baeldung/protobuf/convert/ProtobuffUtil.java
@@ -0,0 +1,37 @@
+package com.baeldung.protobuf.convert;
+
+import java.io.IOException;
+
+import com.google.protobuf.AbstractMessage.Builder;
+import com.google.protobuf.Message;
+import com.google.protobuf.MessageOrBuilder;
+import com.google.protobuf.Struct;
+import com.google.protobuf.util.JsonFormat;
+
+public class ProtobuffUtil {
+
+ public static String toJson(MessageOrBuilder messageOrBuilder) throws IOException {
+ return JsonFormat.printer().print(messageOrBuilder);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T fromJson(String json, Class clazz) throws IOException {
+ Builder> builder = null;
+ try {
+ builder = (Builder>) clazz.getMethod("newBuilder").invoke(null);
+
+ } catch (Exception e) {
+ return null;
+ }
+ JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
+ return (T) builder.build();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Message fromJson(String json) throws IOException {
+ Builder structBuilder = Struct.newBuilder();
+ JsonFormat.parser().ignoringUnknownFields().merge(json, structBuilder);
+ return structBuilder.build();
+ }
+
+}
diff --git a/spring-protobuf/src/test/java/com/baeldung/protobuf/convert/ProtobufUtilUnitTest.java b/spring-protobuf/src/test/java/com/baeldung/protobuf/convert/ProtobufUtilUnitTest.java
new file mode 100644
index 0000000000..61440a2116
--- /dev/null
+++ b/spring-protobuf/src/test/java/com/baeldung/protobuf/convert/ProtobufUtilUnitTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.protobuf.convert;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+
+import com.google.protobuf.Message;
+
+public class ProtobufUtilUnitTest {
+
+ public static String jsonInput = "{\r\n" + " \"boolean\": true,\r\n" + " \"color\": \"gold\",\r\n"
+ + " \"object\": {\r\n" + " \"a\": \"b\",\r\n" + " \"c\": \"d\"\r\n" + " },\r\n"
+ + " \"string\": \"Hello World\"\r\n" + "}";
+
+ @Test
+ public void givenProtobuf_convertToJson() throws IOException {
+ Message fromJson = ProtobuffUtil.fromJson(jsonInput);
+
+ InputStream inputStream = new ByteArrayInputStream(fromJson.toByteArray());
+
+ StringBuilder textBuilder = new StringBuilder();
+ try (Reader reader = new BufferedReader(
+ new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
+ int c = 0;
+ while ((c = reader.read()) != -1) {
+ textBuilder.append((char) c);
+ }
+ }
+ String json = ProtobuffUtil.toJson(fromJson);
+ Assert.assertTrue(json.contains("\"boolean\": true"));
+ Assert.assertTrue(json.contains("\"string\": \"Hello World\""));
+ Assert.assertTrue(json.contains("\"color\": \"gold\""));
+ }
+
+}