-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathJsonBodyHandler.java
More file actions
81 lines (66 loc) · 3.46 KB
/
JsonBodyHandler.java
File metadata and controls
81 lines (66 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package dev.eidentification.bankid.internal.http;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.eidentification.bankid.client.response.ErrorResponse;
import dev.eidentification.bankid.client.response.Response;
import dev.eidentification.bankid.exceptions.BankIdApiErrorException;
import dev.eidentification.bankid.exceptions.BankIdApiUnexpectedResponseException;
import dev.eidentification.bankid.internal.annotations.Internal;
import java.io.InputStream;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
@Internal
public class JsonBodyHandler<R extends Response, E extends ErrorResponse> implements HttpResponse.BodyHandler<R> {
private static final int HTTP_STATUS_OK = 200;
private final Class<R> responseClazz;
private final Class<E> errorResponseClazz;
private final ObjectMapper objectMapper;
JsonBodyHandler(final Class<R> responseClazz, final Class<E> errorResponseClazz, final ObjectMapper objectMapper) {
this.responseClazz = responseClazz;
this.errorResponseClazz = errorResponseClazz;
this.objectMapper = objectMapper;
}
/**
* Returns a {@link HttpResponse.BodySubscriber BodySubscriber}.
*
* @param responseInfo the response info
* @return the body subscriber
* @throws BankIdApiErrorException in case of an api error
* @throws BankIdApiUnexpectedResponseException in case of an unexpected api error
*/
@Override
public HttpResponse.BodySubscriber<R> apply(final HttpResponse.ResponseInfo responseInfo) {
final HttpResponse.BodySubscriber<InputStream> upstream = HttpResponse.BodySubscribers.ofInputStream();
if (responseInfo.statusCode() == HTTP_STATUS_OK) {
return HttpResponse.BodySubscribers.mapping(upstream, inputStream -> inputStreamTo(responseClazz, responseInfo, inputStream));
}
final Optional<String> optionalContentType = responseInfo.headers()
.firstValue("Content-Type")
.map(String::toLowerCase);
if (optionalContentType.isEmpty() || !optionalContentType.get().contains("application/json")) {
return HttpResponse.BodySubscribers.mapping(upstream, inputStream -> {
throw BankIdApiUnexpectedResponseException.of(responseInfo, inputStreamToString(responseInfo, inputStream));
});
}
return HttpResponse.BodySubscribers.mapping(upstream, inputStream -> {
throw BankIdApiErrorException.of(inputStreamTo(errorResponseClazz, responseInfo, inputStream));
});
}
private <T> T inputStreamTo(final Class<T> targetType, final HttpResponse.ResponseInfo responseInfo, final InputStream inputStream) {
String body = "";
try (final InputStream stream = inputStream) {
body = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
return objectMapper.readValue(body, targetType);
} catch (final Exception e) {
throw BankIdApiUnexpectedResponseException.of(responseInfo, body, e);
}
}
private static String inputStreamToString(final HttpResponse.ResponseInfo responseInfo, final InputStream inputStream) {
String body = "";
try (final InputStream stream = inputStream) {
return new String(stream.readAllBytes(), StandardCharsets.UTF_8);
} catch (final Exception e) {
throw BankIdApiUnexpectedResponseException.of(responseInfo, body, e);
}
}
}