diff --git a/jackson-jr/src/main/java/feign/jackson/jr/JacksonJrDecoder.java b/jackson-jr/src/main/java/feign/jackson/jr/JacksonJrDecoder.java index ef74ceca8..c720b77bd 100644 --- a/jackson-jr/src/main/java/feign/jackson/jr/JacksonJrDecoder.java +++ b/jackson-jr/src/main/java/feign/jackson/jr/JacksonJrDecoder.java @@ -93,9 +93,6 @@ public Object decode(Response response, Type type) throws IOException { } protected Transformer findTransformer(Response response, Type type) { - if (type instanceof Class) { - return (mapper, reader) -> mapper.beanFrom((Class) type, reader); - } if (type instanceof ParameterizedType) { Type rawType = ((ParameterizedType) type).getRawType(); Type[] parameterType = ((ParameterizedType) type).getActualTypeArguments(); @@ -105,6 +102,11 @@ protected Transformer findTransformer(Response response, Type type) { if (rawType.equals(Map.class)) { return (mapper, reader) -> mapper.mapOfFrom((Class) parameterType[1], reader); } + type = rawType; + } + if (type instanceof Class) { + Class clazz = (Class) type; + return (mapper, reader) -> mapper.beanFrom(clazz, reader); } throw new DecodeException(500, "Cannot decode type: " + type.getTypeName(), response.request()); } diff --git a/jackson-jr/src/test/java/feign/jackson/jr/JacksonCodecTest.java b/jackson-jr/src/test/java/feign/jackson/jr/JacksonCodecTest.java index 7124e9c03..937caa43c 100644 --- a/jackson-jr/src/test/java/feign/jackson/jr/JacksonCodecTest.java +++ b/jackson-jr/src/test/java/feign/jackson/jr/JacksonCodecTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 The Feign Authors + * Copyright 2012-2024 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -16,8 +16,8 @@ import static feign.Util.UTF_8; import static feign.assertj.FeignAssertions.assertThat; import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; +import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.util.Arrays; @@ -29,6 +29,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Stream; + import org.junit.jupiter.api.Test; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.jr.ob.JSON; @@ -37,6 +39,9 @@ import feign.RequestTemplate; import feign.Response; import feign.Util; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class JacksonCodecTest { @@ -289,4 +294,57 @@ void notFoundDecodesToEmpty() throws Exception { .build(); assertThat((byte[]) new JacksonJrDecoder().decode(response, byte[].class)).isEmpty(); } + + @ParameterizedTest + @MethodSource("decodeGenericsArguments") + void decodeGenerics(Response response, Type responseType, DataWrapper expectedDataWrapper) throws IOException { + assertThat(new JacksonJrDecoder().decode(response, responseType)).isEqualTo(expectedDataWrapper); + } + + static class DataWrapper { + private T data; + + DataWrapper() { + } + + DataWrapper(T data) { + this.data = data; + } + + public void setData(T data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DataWrapper that = (DataWrapper) o; + return Objects.equals(data, that.data); + } + } + + static Stream decodeGenericsArguments() { + Response.Builder responseBuilder = Response + .builder() + .request(Request.create( + HttpMethod.GET, + "/v1/dummy", + Collections.emptyMap(), + Request.Body.empty(), + null + )); + return Stream.of( + Arguments.of( + responseBuilder.body("{\"data\":2024}", StandardCharsets.UTF_8).build(), + new TypeReference>() {}.getType(), + new DataWrapper<>(2024) + ), + Arguments.of( + responseBuilder.body("{\"data\":\"Hello, World!\"}", StandardCharsets.UTF_8).build(), + new TypeReference>() {}.getType(), + new DataWrapper<>("Hello, World!") + ) + ); + } }