diff --git a/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java b/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java index aa9dd9d..0593d8a 100644 --- a/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java +++ b/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java @@ -36,7 +36,7 @@ final class DefaultProblemAdapter extends TypeAdapter { gson, stackTraces, gson.getAdapter(String.class), - URITypeAdapter.TYPE, + gson.getAdapter(URI.class), gson.getAdapter(new TypeToken>() { // nothing to do here }), @@ -48,7 +48,7 @@ final class DefaultProblemAdapter extends TypeAdapter { public void write(final JsonWriter out, final ThrowableProblem problem) throws IOException { final JsonObject object = new JsonObject(); - object.add("type", uriAdapter.toJsonTree(problem.getType())); + object.add("type", URITypeAdapter.TYPE.toJsonTree(problem.getType())); object.add("title", stringAdapter.toJsonTree(problem.getTitle())); object.add("status", status.toJsonTree(problem.getStatus())); object.add("detail", stringAdapter.toJsonTree(problem.getDetail())); @@ -78,7 +78,7 @@ public ThrowableProblem read(final JsonReader in) throws IOException { final String name = in.nextName(); switch (name) { case "type": - builder.withType(uriAdapter.read(in)); + builder.withType(URITypeAdapter.TYPE.read(in)); break; case "title": builder.withTitle(stringAdapter.read(in)); diff --git a/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java index 82b2636..31e4ee8 100644 --- a/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java +++ b/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java @@ -83,6 +83,52 @@ void shouldSerializeCustomProperties() { .assertThat("$.product", is("B00027Y5QG")); } + @Test + void shouldPreserveNullInstance() { + final Problem problem = gson.fromJson("{\"instance\":null}", Problem.class); + + assertThat(problem.getInstance(), is(nullValue())); + assertThat(problem.getType(), is(Problem.DEFAULT_TYPE)); + } + + @Test + void shouldRoundTripNullInstance() { + final Gson gson = new GsonBuilder() + .registerTypeAdapterFactory(new ProblemAdapterFactory()) + .serializeNulls() + .create(); + final Problem problem = Problem.valueOf(BAD_REQUEST); + + final Problem copy = gson.fromJson(gson.toJson(problem), Problem.class); + + assertThat(copy.getInstance(), is(nullValue())); + assertThat(copy.getType(), is(Problem.DEFAULT_TYPE)); + } + + @Test + void shouldPreserveAboutBlankInstance() { + final Problem problem = Problem.builder() + .withInstance(URI.create("about:blank")) + .build(); + + final String json = gson.toJson(problem); + + with(json).assertThat("$.instance", is("about:blank")); + assertThat(gson.fromJson(json, Problem.class).getInstance(), is(problem.getInstance())); + } + + @Test + void shouldRoundTripRelativeInstance() { + final Problem problem = Problem.builder() + .withInstance(URI.create("/problems/123")) + .build(); + + final String json = gson.toJson(problem); + + with(json).assertThat("$.instance", is("/problems/123")); + assertThat(gson.fromJson(json, Problem.class).getInstance(), is(problem.getInstance())); + } + @Test void shouldSerializeCustomProblem() { final int balance = 10;