diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
index 7ca03c70e3..163a129297 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
@@ -63,6 +63,11 @@
org.apache.avro
avro
+
+ joda-time
+ joda-time
+ compile
+
org.xerial.snappy
snappy-java
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
index d8cb37d45d..cf532c3a28 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
@@ -18,11 +18,16 @@ package org.apache.nifi.web;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.avro.Conversions;
+import org.apache.avro.data.TimeConversions;
import org.apache.avro.file.DataFileStream;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.io.DatumReader;
import org.apache.nifi.web.ViewableContent.DisplayMode;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalTime;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -103,11 +108,27 @@ public class StandardContentViewerController extends HttpServlet {
} else if ("application/avro-binary".equals(contentType) || "avro/binary".equals(contentType) || "application/avro+binary".equals(contentType)) {
final StringBuilder sb = new StringBuilder();
sb.append("[");
- final DatumReader datumReader = new GenericDatumReader<>();
+ // Use Avro conversions to display logical type values in human readable way.
+ final GenericData genericData = new GenericData(){
+ @Override
+ protected void toString(Object datum, StringBuilder buffer) {
+ // Since these types are not quoted and produce a malformed JSON string, quote it here.
+ if (datum instanceof LocalDate || datum instanceof LocalTime || datum instanceof DateTime) {
+ buffer.append("\"").append(datum).append("\"");
+ return;
+ }
+ super.toString(datum, buffer);
+ }
+ };
+ genericData.addLogicalTypeConversion(new Conversions.DecimalConversion());
+ genericData.addLogicalTypeConversion(new TimeConversions.DateConversion());
+ genericData.addLogicalTypeConversion(new TimeConversions.TimeConversion());
+ genericData.addLogicalTypeConversion(new TimeConversions.TimestampConversion());
+ final DatumReader datumReader = new GenericDatumReader<>(null, null, genericData);
try (final DataFileStream dataFileReader = new DataFileStream<>(content.getContentStream(), datumReader)) {
while (dataFileReader.hasNext()) {
final GenericData.Record record = dataFileReader.next();
- final String formattedRecord = record.toString();
+ final String formattedRecord = genericData.toString(record);
sb.append(formattedRecord);
sb.append(",");
// Do not format more than 10 MB of content.