Skip to content

Commit

Permalink
Merge pull request #1332 from scireum/feature/mke/SIRI-911_json_jackson
Browse files Browse the repository at this point in the history
Let Jackson serialize it's own object types
  • Loading branch information
mkeckmkeck authored Dec 5, 2023
2 parents ca9b356 + bcf5ec3 commit dec996f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<description>Provides a modern and scalable web server as SIRIUS module</description>

<properties>
<sirius.kernel>dev-40.0.0</sirius.kernel>
<sirius.kernel>dev-41.0.0</sirius.kernel>
</properties>

<repositories>
Expand Down
28 changes: 16 additions & 12 deletions src/main/java/sirius/web/services/JSONStructuredOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,27 @@ public StructuredOutput beginResult(String name) {

@Override
public void writeProperty(String name, Object data) {
if (data instanceof ObjectNode jsonObject) {
beginObject(name);
jsonObject.properties().forEach(entry -> property(entry.getKey(), entry.getValue()));
endObject();
} else if (data instanceof ArrayNode jsonArray) {
beginArray(name);
jsonArray.forEach(element -> property("", element));
endArray();
} else if (data instanceof POJONode pojoNode) {
writeProperty(name, pojoNode.getPojo());
} else if (data instanceof JsonNode jsonNode) {
writePlainProperty(name, Json.convertToJavaObject(jsonNode));
if (data instanceof JsonNode jsonNode) {
writePreformattedProperty(name, jsonNode.toString());
} else {
writePlainProperty(name, data);
}
}

private void writePreformattedProperty(String name, String value) {
try {
addRequiredComma();
addObjectName(name);
if (value == null) {
writer.write("null");
return;
}
writer.write(value);
} catch (IOException exception) {
throw handleOutputException(exception);
}
}

private void writePlainProperty(String name, Object data) {
try {
addRequiredComma();
Expand Down
58 changes: 55 additions & 3 deletions src/test/java/sirius/web/service/JSONStructuredOutputTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@

package sirius.web.service;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.POJONode;
import org.junit.jupiter.api.Test;
import sirius.kernel.commons.Amount;
import sirius.kernel.commons.Json;
import sirius.web.services.JSONStructuredOutput;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

Expand All @@ -34,14 +38,62 @@ void writeEmptyArray() {
}

@Test
void writeAmountWithinJacksonObject() {
void writeAmountsWithinJacksonObject() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JSONStructuredOutput out = new JSONStructuredOutput(byteArrayOutputStream, null, StandardCharsets.UTF_8.name());

ObjectNode objectNodeWithAmount = Json.createObject().putPOJO("amount", Amount.of(1.23));
ObjectNode objectNodeWithAmount = Json.createObject();
objectNodeWithAmount.putPOJO("amountDefault", Amount.of(1.234567));
objectNodeWithAmount.putPOJO("amountRounded", Amount.ofRounded(BigDecimal.valueOf(1.234567)));
objectNodeWithAmount.putPOJO("amountNothing", Amount.NOTHING);
out.writeProperty(null, objectNodeWithAmount);
out.finalizeOutput();

assertEquals("{\"amount\":1.23}", byteArrayOutputStream.toString());
assertEquals("""
{"amountDefault":1.23,"amountRounded":1.234567,"amountNothing":null}""",
byteArrayOutputStream.toString());
}

@Test
void writeJacksonArrayWithObjects() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JSONStructuredOutput out = new JSONStructuredOutput(byteArrayOutputStream, null, StandardCharsets.UTF_8.name());

ArrayNode array = Json.createArray(List.of(new AnObject("a", 1), new AnObject("b", 2)));
out.writeProperty(null, array);
out.finalizeOutput();

assertEquals("""
[{"field1":"a","field2":1},{"field1":"b","field2":2}]""", byteArrayOutputStream.toString());
}

@Test
void writeJacksonPojoWithObject() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JSONStructuredOutput out = new JSONStructuredOutput(byteArrayOutputStream, null, StandardCharsets.UTF_8.name());

out.writeProperty(null, new POJONode(new AnObject("a", 1)));
out.finalizeOutput();

assertEquals("""
{"field1":"a","field2":1}""", byteArrayOutputStream.toString());
}

private static class AnObject {
private final String field1;
private final int field2;

public AnObject(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}

public String getField1() {
return field1;
}

public int getField2() {
return field2;
}
}
}

0 comments on commit dec996f

Please sign in to comment.