forked from OpenFeign/feign
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJAXRSClient.java
More file actions
134 lines (111 loc) · 4.09 KB
/
JAXRSClient.java
File metadata and controls
134 lines (111 loc) · 4.09 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* Copyright 2012-2020 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.jaxrs2;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.*;
import feign.Client;
import feign.Request.Options;
/**
* This module directs Feign's http requests to javax.ws.rs.client.Client . Ex:
*
* <pre>
* GitHub github =
* Feign.builder().client(new JaxRSClient()).target(GitHub.class, "https://api.github.com");
* </pre>
*/
public class JAXRSClient implements Client {
private final ClientBuilder clientBuilder;
public JAXRSClient() {
this(ClientBuilder.newBuilder());
}
public JAXRSClient(ClientBuilder clientBuilder) {
this.clientBuilder = clientBuilder;
}
@Override
public feign.Response execute(feign.Request request, Options options) throws IOException {
final Response response = clientBuilder
.connectTimeout(options.connectTimeoutMillis(), TimeUnit.MILLISECONDS)
.readTimeout(options.readTimeoutMillis(), TimeUnit.MILLISECONDS)
.build()
.target(request.url())
.request()
.headers(toMultivaluedMap(request.headers()))
.method(request.httpMethod().name(), createRequestEntity(request));
return feign.Response.builder()
.request(request)
.body(response.readEntity(InputStream.class),
integerHeader(response, HttpHeaders.CONTENT_LENGTH))
.headers(toMap(response.getStringHeaders()))
.status(response.getStatus())
.reason(response.getStatusInfo().getReasonPhrase())
.build();
}
private Entity<byte[]> createRequestEntity(feign.Request request) {
if (request.body() == null) {
return null;
}
return Entity.entity(
request.body(),
new Variant(mediaType(request.headers()), locale(request.headers()),
encoding(request.charset())));
}
private Integer integerHeader(Response response, String header) {
final MultivaluedMap<String, String> headers = response.getStringHeaders();
if (!headers.containsKey(header)) {
return null;
}
try {
return new Integer(headers.getFirst(header));
} catch (final NumberFormatException e) {
// not a number or too big to fit Integer
return null;
}
}
private String encoding(Charset charset) {
if (charset == null)
return null;
return charset.name();
}
private String locale(Map<String, Collection<String>> headers) {
if (!headers.containsKey(HttpHeaders.CONTENT_LANGUAGE))
return null;
return headers.get(HttpHeaders.CONTENT_LANGUAGE).iterator().next();
}
private MediaType mediaType(Map<String, Collection<String>> headers) {
if (!headers.containsKey(HttpHeaders.CONTENT_TYPE))
return null;
return MediaType.valueOf(headers.get(HttpHeaders.CONTENT_TYPE).iterator().next());
}
private MultivaluedMap<String, Object> toMultivaluedMap(Map<String, Collection<String>> headers) {
final MultivaluedHashMap<String, Object> mvHeaders = new MultivaluedHashMap<>();
headers.forEach((key, value1) -> value1
.forEach(value -> mvHeaders.add(key, value)));
return mvHeaders;
}
private Map<String, Collection<String>> toMap(MultivaluedMap<String, String> headers) {
return headers.entrySet().stream()
.collect(Collectors.toMap(
Entry::getKey,
Entry::getValue));
}
}