1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gbif.ws.client;
15
16 import java.io.IOException;
17 import java.lang.reflect.Type;
18 import java.nio.charset.StandardCharsets;
19
20 import org.springframework.http.HttpHeaders;
21 import org.springframework.http.HttpStatus;
22 import org.springframework.http.MediaType;
23 import org.springframework.util.StringUtils;
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26
27 import feign.FeignException;
28 import feign.Response;
29 import feign.Util;
30 import feign.codec.DecodeException;
31 import feign.codec.Decoder;
32 import feign.jackson.JacksonDecoder;
33
34 public class ClientDecoder implements Decoder {
35
36 private final JacksonDecoder jacksonDecoder;
37
38 public ClientDecoder(ObjectMapper objectMapper) {
39 this.jacksonDecoder = new JacksonDecoder(objectMapper);
40 }
41
42 @Override
43 public Object decode(Response response, Type type) throws IOException, FeignException {
44 HttpStatus responseStatus = HttpStatus.resolve(response.status());
45
46 if (responseStatus == HttpStatus.NOT_FOUND || responseStatus == HttpStatus.NO_CONTENT) {
47 return null;
48 } else if (responseStatus != null && responseStatus.isError()) {
49 throw new DecodeException(response.status(), response.toString(), response.request());
50 }
51
52 MediaType contentType = getContentType(response);
53 if (MediaType.APPLICATION_JSON.equalsTypeAndSubtype(contentType)) {
54 return jacksonDecoder.decode(response, type);
55 } else if (MediaType.TEXT_PLAIN.equalsTypeAndSubtype(contentType)) {
56 return Util.toString(response.body().asReader(StandardCharsets.UTF_8));
57 } else if (MediaType.APPLICATION_OCTET_STREAM.equalsTypeAndSubtype(contentType)) {
58 return Util.toByteArray(response.body().asInputStream());
59 } else if (byte[].class.equals(type)) {
60 return Util.toByteArray(response.body().asInputStream());
61 } else {
62 throw new DecodeException(response.status(), "Unsupported response type", response.request());
63 }
64 }
65
66
67
68
69 private static MediaType getContentType(Response response) {
70 return response.headers().get(HttpHeaders.CONTENT_TYPE).stream()
71 .findFirst()
72 .filter(StringUtils::hasLength)
73 .map(MediaType::parseMediaType)
74 .orElse(null);
75 }
76 }