forked from loafle/openapi-generator-original
		
	[Java][client] Fix feign classcastexception when getting headers (#16745)
* Avoid ClassCastException when getting headers (the header values are Collection<String> and not List<String>) Delete unused classes * Remove feign10x * Add unit test Refactor to avoid creating the headers map when ApiResponse is not used
This commit is contained in:
		
							parent
							
								
									494ee489ad
								
							
						
					
					
						commit
						87f9d53c3a
					
				
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -49,8 +49,6 @@ nb-configuration.xml
 | 
				
			|||||||
/target
 | 
					/target
 | 
				
			||||||
/generated-files
 | 
					/generated-files
 | 
				
			||||||
test-output/
 | 
					test-output/
 | 
				
			||||||
nbactions.xml
 | 
					 | 
				
			||||||
test-output/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# website
 | 
					# website
 | 
				
			||||||
website/build/
 | 
					website/build/
 | 
				
			||||||
@ -73,7 +71,6 @@ samples/client/petstore/build
 | 
				
			|||||||
samples/client/petstore/cpp-qt/PetStore/moc_*
 | 
					samples/client/petstore/cpp-qt/PetStore/moc_*
 | 
				
			||||||
samples/client/petstore/cpp-qt/PetStore/*.o
 | 
					samples/client/petstore/cpp-qt/PetStore/*.o
 | 
				
			||||||
samples/client/petstore/cpp-qt/build-*
 | 
					samples/client/petstore/cpp-qt/build-*
 | 
				
			||||||
samples/client/petstore/cpp-qt/build-*
 | 
					 | 
				
			||||||
samples/client/petstore/cpp-qt/PetStore/PetStore
 | 
					samples/client/petstore/cpp-qt/PetStore/PetStore
 | 
				
			||||||
samples/client/petstore/cpp-qt/PetStore/Makefile
 | 
					samples/client/petstore/cpp-qt/PetStore/Makefile
 | 
				
			||||||
samples/client/petstore/cpp-qt/PetStore/PetStore.pro.user
 | 
					samples/client/petstore/cpp-qt/PetStore/PetStore.pro.user
 | 
				
			||||||
@ -100,9 +97,7 @@ samples/client/petstore/java/jersey2/build/
 | 
				
			|||||||
samples/client/petstore/java/okhttp-gson/.gradle/
 | 
					samples/client/petstore/java/okhttp-gson/.gradle/
 | 
				
			||||||
samples/client/petstore/java/okhttp-gson/build/
 | 
					samples/client/petstore/java/okhttp-gson/build/
 | 
				
			||||||
samples/client/petstore/java/feign/build/
 | 
					samples/client/petstore/java/feign/build/
 | 
				
			||||||
samples/client/petstore/java/feign10x/build/
 | 
					 | 
				
			||||||
samples/client/petstore/java/feign/project/
 | 
					samples/client/petstore/java/feign/project/
 | 
				
			||||||
samples/client/petstore/java/feign10x/project/
 | 
					 | 
				
			||||||
samples/client/petstore/java/retrofit/build/
 | 
					samples/client/petstore/java/retrofit/build/
 | 
				
			||||||
samples/client/petstore/java/retrofit2/build/
 | 
					samples/client/petstore/java/retrofit2/build/
 | 
				
			||||||
samples/client/petstore/java/retrofit2/hello.txt
 | 
					samples/client/petstore/java/retrofit2/hello.txt
 | 
				
			||||||
@ -110,7 +105,6 @@ samples/client/petstore/java/retrofit2rx/build/
 | 
				
			|||||||
samples/client/petstore/java/default/build/
 | 
					samples/client/petstore/java/default/build/
 | 
				
			||||||
samples/client/petstore/scala/build/
 | 
					samples/client/petstore/scala/build/
 | 
				
			||||||
samples/client/petstore/java/resttemplate/hello.txt
 | 
					samples/client/petstore/java/resttemplate/hello.txt
 | 
				
			||||||
samples/client/petstore/java/retrofit2/hello.txt
 | 
					 | 
				
			||||||
samples/client/petstore/java/feign/hello.txt
 | 
					samples/client/petstore/java/feign/hello.txt
 | 
				
			||||||
samples/client/petstore/java/jersey2-java6/project/
 | 
					samples/client/petstore/java/jersey2-java6/project/
 | 
				
			||||||
samples/client/petstore/java/jersey2-java8/project/
 | 
					samples/client/petstore/java/jersey2-java8/project/
 | 
				
			||||||
 | 
				
			|||||||
@ -22,14 +22,13 @@ public class ApiResponseDecoder extends JacksonDecoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Object decode(Response response, Type type) throws IOException {
 | 
					    public Object decode(Response response, Type type) throws IOException {
 | 
				
			||||||
    Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
					 | 
				
			||||||
        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
					        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
				
			||||||
        Type responseBodyType;
 | 
					 | 
				
			||||||
        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
					        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
				
			||||||
            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
					            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
				
			||||||
            responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
					            Type responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
				
			||||||
            Object body = super.decode(response, responseBodyType);
 | 
					            Object body = super.decode(response, responseBodyType);
 | 
				
			||||||
            return new ApiResponse(response.status(), responseHeaders, body);
 | 
					            Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
				
			||||||
 | 
					            return new ApiResponse<>(response.status(), responseHeaders, body);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
					            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
				
			||||||
            return super.decode(response, type);
 | 
					            return super.decode(response, type);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,19 @@
 | 
				
			|||||||
package {{modelPackage}};
 | 
					package {{modelPackage}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ApiResponse<T>{
 | 
					public class ApiResponse<T>{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final private int statusCode;
 | 
					    final private int statusCode;
 | 
				
			||||||
    final private Map<String, List<String>> headers;
 | 
					    final private Map<String, Collection<String>> headers;
 | 
				
			||||||
    final private T data;
 | 
					    final private T data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param statusCode The status code of HTTP response
 | 
					     * @param statusCode The status code of HTTP response
 | 
				
			||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers) {
 | 
				
			||||||
        this(statusCode, headers, null);
 | 
					        this(statusCode, headers, null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,7 +22,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     * @param data The object deserialized from response bod
 | 
					     * @param data The object deserialized from response bod
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers, T data) {
 | 
				
			||||||
        this.statusCode = statusCode;
 | 
					        this.statusCode = statusCode;
 | 
				
			||||||
        this.headers = headers;
 | 
					        this.headers = headers;
 | 
				
			||||||
        this.data = data;
 | 
					        this.data = data;
 | 
				
			||||||
@ -32,7 +32,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
        return statusCode;
 | 
					        return statusCode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Map<String, List<String>> getHeaders() {
 | 
					    public Map<String, Collection<String>> getHeaders() {
 | 
				
			||||||
        return headers;
 | 
					        return headers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,19 @@
 | 
				
			|||||||
package org.openapitools.client.model;
 | 
					package org.openapitools.client.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ApiResponse<T>{
 | 
					public class ApiResponse<T>{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final private int statusCode;
 | 
					    final private int statusCode;
 | 
				
			||||||
    final private Map<String, List<String>> headers;
 | 
					    final private Map<String, Collection<String>> headers;
 | 
				
			||||||
    final private T data;
 | 
					    final private T data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param statusCode The status code of HTTP response
 | 
					     * @param statusCode The status code of HTTP response
 | 
				
			||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers) {
 | 
				
			||||||
        this(statusCode, headers, null);
 | 
					        this(statusCode, headers, null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,7 +22,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     * @param data The object deserialized from response bod
 | 
					     * @param data The object deserialized from response bod
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers, T data) {
 | 
				
			||||||
        this.statusCode = statusCode;
 | 
					        this.statusCode = statusCode;
 | 
				
			||||||
        this.headers = headers;
 | 
					        this.headers = headers;
 | 
				
			||||||
        this.data = data;
 | 
					        this.data = data;
 | 
				
			||||||
@ -32,7 +32,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
        return statusCode;
 | 
					        return statusCode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Map<String, List<String>> getHeaders() {
 | 
					    public Map<String, Collection<String>> getHeaders() {
 | 
				
			||||||
        return headers;
 | 
					        return headers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,14 +22,13 @@ public class ApiResponseDecoder extends JacksonDecoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Object decode(Response response, Type type) throws IOException {
 | 
					    public Object decode(Response response, Type type) throws IOException {
 | 
				
			||||||
    Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
					 | 
				
			||||||
        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
					        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
				
			||||||
        Type responseBodyType;
 | 
					 | 
				
			||||||
        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
					        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
				
			||||||
            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
					            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
				
			||||||
            responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
					            Type responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
				
			||||||
            Object body = super.decode(response, responseBodyType);
 | 
					            Object body = super.decode(response, responseBodyType);
 | 
				
			||||||
            return new ApiResponse(response.status(), responseHeaders, body);
 | 
					            Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
				
			||||||
 | 
					            return new ApiResponse<>(response.status(), responseHeaders, body);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
					            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
				
			||||||
            return super.decode(response, type);
 | 
					            return super.decode(response, type);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,38 +0,0 @@
 | 
				
			|||||||
package org.openapitools.client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
					 | 
				
			||||||
import feign.Response;
 | 
					 | 
				
			||||||
import feign.Types;
 | 
					 | 
				
			||||||
import feign.jackson.JacksonDecoder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.lang.reflect.ParameterizedType;
 | 
					 | 
				
			||||||
import java.lang.reflect.Type;
 | 
					 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
import java.util.Collections;
 | 
					 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.openapitools.client.model.HttpResponse;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class JacksonResponseDecoder extends JacksonDecoder {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public JacksonResponseDecoder(ObjectMapper mapper) {
 | 
					 | 
				
			||||||
        super(mapper);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public Object decode(Response response, Type type) throws IOException {
 | 
					 | 
				
			||||||
    Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
					 | 
				
			||||||
        //Detects if the type is an instance of the parameterized class HttpResponse
 | 
					 | 
				
			||||||
        Type responseBodyType;
 | 
					 | 
				
			||||||
        if (Types.getRawType(type).isAssignableFrom(HttpResponse.class)) {
 | 
					 | 
				
			||||||
            //The HttpResponse class has a single type parameter, the Dto class itself
 | 
					 | 
				
			||||||
            responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
					 | 
				
			||||||
            Object body = super.decode(response, responseBodyType);
 | 
					 | 
				
			||||||
            return new HttpResponse(responseHeaders, body, response.status());
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            //The response is not encapsulated in the HttpResponse, decode the Dto as normal
 | 
					 | 
				
			||||||
            return super.decode(response, type);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,19 +1,19 @@
 | 
				
			|||||||
package org.openapitools.client.model;
 | 
					package org.openapitools.client.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ApiResponse<T>{
 | 
					public class ApiResponse<T>{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final private int statusCode;
 | 
					    final private int statusCode;
 | 
				
			||||||
    final private Map<String, List<String>> headers;
 | 
					    final private Map<String, Collection<String>> headers;
 | 
				
			||||||
    final private T data;
 | 
					    final private T data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param statusCode The status code of HTTP response
 | 
					     * @param statusCode The status code of HTTP response
 | 
				
			||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers) {
 | 
				
			||||||
        this(statusCode, headers, null);
 | 
					        this(statusCode, headers, null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,7 +22,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     * @param data The object deserialized from response bod
 | 
					     * @param data The object deserialized from response bod
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers, T data) {
 | 
				
			||||||
        this.statusCode = statusCode;
 | 
					        this.statusCode = statusCode;
 | 
				
			||||||
        this.headers = headers;
 | 
					        this.headers = headers;
 | 
				
			||||||
        this.data = data;
 | 
					        this.data = data;
 | 
				
			||||||
@ -32,7 +32,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
        return statusCode;
 | 
					        return statusCode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Map<String, List<String>> getHeaders() {
 | 
					    public Map<String, Collection<String>> getHeaders() {
 | 
				
			||||||
        return headers;
 | 
					        return headers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,31 +0,0 @@
 | 
				
			|||||||
package org.openapitools.client.model;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class HttpResponse<T>{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private Map<String, Collection<String>> headers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private T body;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private int status;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public HttpResponse(Map<String, Collection<String>> headers, T body, int status) {
 | 
					 | 
				
			||||||
    this.headers = headers;
 | 
					 | 
				
			||||||
    this.body = body;
 | 
					 | 
				
			||||||
    this.status = status;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public T getBody(){
 | 
					 | 
				
			||||||
    return body;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public Map<String, Collection<String>> getHeaders(){
 | 
					 | 
				
			||||||
    return headers;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public int getStatus(){
 | 
					 | 
				
			||||||
    return status;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -22,14 +22,13 @@ public class ApiResponseDecoder extends JacksonDecoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Object decode(Response response, Type type) throws IOException {
 | 
					    public Object decode(Response response, Type type) throws IOException {
 | 
				
			||||||
    Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
					 | 
				
			||||||
        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
					        //Detects if the type is an instance of the parameterized class ApiResponse
 | 
				
			||||||
        Type responseBodyType;
 | 
					 | 
				
			||||||
        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
					        if (type instanceof ParameterizedType && Types.getRawType(type).isAssignableFrom(ApiResponse.class)) {
 | 
				
			||||||
            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
					            //The ApiResponse class has a single type parameter, the Dto class itself
 | 
				
			||||||
            responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
					            Type responseBodyType = ((ParameterizedType) type).getActualTypeArguments()[0];
 | 
				
			||||||
            Object body = super.decode(response, responseBodyType);
 | 
					            Object body = super.decode(response, responseBodyType);
 | 
				
			||||||
            return new ApiResponse(response.status(), responseHeaders, body);
 | 
					            Map<String, Collection<String>> responseHeaders = Collections.unmodifiableMap(response.headers());
 | 
				
			||||||
 | 
					            return new ApiResponse<>(response.status(), responseHeaders, body);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
					            //The response is not encapsulated in the ApiResponse, decode the Dto as normal
 | 
				
			||||||
            return super.decode(response, type);
 | 
					            return super.decode(response, type);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,19 @@
 | 
				
			|||||||
package org.openapitools.client.model;
 | 
					package org.openapitools.client.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ApiResponse<T>{
 | 
					public class ApiResponse<T>{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final private int statusCode;
 | 
					    final private int statusCode;
 | 
				
			||||||
    final private Map<String, List<String>> headers;
 | 
					    final private Map<String, Collection<String>> headers;
 | 
				
			||||||
    final private T data;
 | 
					    final private T data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param statusCode The status code of HTTP response
 | 
					     * @param statusCode The status code of HTTP response
 | 
				
			||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers) {
 | 
				
			||||||
        this(statusCode, headers, null);
 | 
					        this(statusCode, headers, null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,7 +22,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
     * @param headers The headers of HTTP response
 | 
					     * @param headers The headers of HTTP response
 | 
				
			||||||
     * @param data The object deserialized from response bod
 | 
					     * @param data The object deserialized from response bod
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
 | 
					    public ApiResponse(int statusCode, Map<String, Collection<String>> headers, T data) {
 | 
				
			||||||
        this.statusCode = statusCode;
 | 
					        this.statusCode = statusCode;
 | 
				
			||||||
        this.headers = headers;
 | 
					        this.headers = headers;
 | 
				
			||||||
        this.data = data;
 | 
					        this.data = data;
 | 
				
			||||||
@ -32,7 +32,7 @@ public class ApiResponse<T>{
 | 
				
			|||||||
        return statusCode;
 | 
					        return statusCode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Map<String, List<String>> getHeaders() {
 | 
					    public Map<String, Collection<String>> getHeaders() {
 | 
				
			||||||
        return headers;
 | 
					        return headers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					package org.openapitools.client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.jupiter.api.Assertions.assertEquals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.databind.ObjectMapper;
 | 
				
			||||||
 | 
					import com.google.common.collect.ImmutableMap;
 | 
				
			||||||
 | 
					import feign.Request;
 | 
				
			||||||
 | 
					import feign.Request.HttpMethod;
 | 
				
			||||||
 | 
					import feign.RequestTemplate;
 | 
				
			||||||
 | 
					import feign.Response;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
 | 
					import org.junit.jupiter.api.Test;
 | 
				
			||||||
 | 
					import org.openapitools.client.model.ApiResponse;
 | 
				
			||||||
 | 
					import org.openapitools.client.model.Cat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ApiResponseDecoderTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private final ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ApiResponseDecoder decoder = new ApiResponseDecoder(objectMapper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Test
 | 
				
			||||||
 | 
					  void shouldDecodeApiResponseWithHeaders() throws IOException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final Cat cat = makeCat();
 | 
				
			||||||
 | 
					    TypeReference<ApiResponse<Cat>> typeReference = new TypeReference<ApiResponse<Cat>>() {
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ApiResponse<Cat> response = (ApiResponse<Cat>) decoder.decode(Response.builder()
 | 
				
			||||||
 | 
					        .headers(ImmutableMap.of("Location",
 | 
				
			||||||
 | 
					            Collections.singletonList("https://example.com/cats/1")))
 | 
				
			||||||
 | 
					        .body(objectMapper.writeValueAsBytes(cat))
 | 
				
			||||||
 | 
					        .status(201)
 | 
				
			||||||
 | 
					        .request(buildRequest())
 | 
				
			||||||
 | 
					        .build(), typeReference.getType());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assertEquals(cat.getColor(), response.getData().getColor());
 | 
				
			||||||
 | 
					    assertEquals(cat.isDeclawed(), response.getData().isDeclawed());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Collection<String> locationValues = response.getHeaders().get("Location");
 | 
				
			||||||
 | 
					    assertEquals(1, locationValues.size());
 | 
				
			||||||
 | 
					    assertEquals("https://example.com/cats/1", locationValues.iterator().next());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Cat makeCat() {
 | 
				
			||||||
 | 
					    final Cat cat = new Cat();
 | 
				
			||||||
 | 
					    cat.color("black");
 | 
				
			||||||
 | 
					    cat.declawed(true);
 | 
				
			||||||
 | 
					    return cat;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Request buildRequest() {
 | 
				
			||||||
 | 
					    return Request.create(HttpMethod.GET, "https://example.com/cats/1", Collections.emptyMap(),
 | 
				
			||||||
 | 
					        null, new RequestTemplate());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user