1 package org.oxerr.okcoin.rest.service.web;
2
3 import static java.util.Collections.emptyMap;
4
5 import java.io.IOException;
6 import java.net.URI;
7 import java.net.URISyntaxException;
8 import java.nio.charset.Charset;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Optional;
15
16 import javax.annotation.Nullable;
17
18 import org.apache.http.Header;
19 import org.apache.http.NameValuePair;
20 import org.apache.http.client.config.RequestConfig;
21 import org.apache.http.client.entity.UrlEncodedFormEntity;
22 import org.apache.http.client.methods.CloseableHttpResponse;
23 import org.apache.http.client.methods.HttpGet;
24 import org.apache.http.client.methods.HttpPost;
25 import org.apache.http.client.methods.HttpUriRequest;
26 import org.apache.http.client.utils.URIBuilder;
27 import org.apache.http.entity.ContentType;
28 import org.apache.http.entity.StringEntity;
29 import org.apache.http.impl.client.CloseableHttpClient;
30 import org.apache.http.impl.client.HttpClientBuilder;
31 import org.apache.http.impl.client.LaxRedirectStrategy;
32 import org.apache.http.message.BasicHeader;
33 import org.apache.http.message.BasicNameValuePair;
34 import org.oxerr.okcoin.rest.dto.valuereader.JsonValueReader;
35 import org.oxerr.okcoin.rest.dto.valuereader.JsonValueTypeRefReader;
36 import org.oxerr.okcoin.rest.dto.valuereader.ValueReader;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import com.fasterxml.jackson.core.JsonParser.Feature;
41 import com.fasterxml.jackson.core.type.TypeReference;
42 import com.fasterxml.jackson.databind.ObjectMapper;
43
44 public class HttpClient implements AutoCloseable {
45
46 private final Logger log = LoggerFactory.getLogger(HttpClient.class);
47
48 private final CloseableHttpClient httpClient;
49
50 private final ObjectMapper objectMapper;
51
52 public HttpClient(CloseableHttpClient httpClient, ObjectMapper objectMapper) {
53 this.httpClient = httpClient;
54 this.objectMapper = objectMapper;
55 }
56
57 public HttpClient(
58 int socketTimeout,
59 int connectTimeout,
60 int connectionRequestTimeout) {
61 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
62 httpClientBuilder.setRedirectStrategy(new LaxRedirectStrategy());
63
64 String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.71 (KHTML, like Gecko) Version/6.1 Safari/537.71";
65 httpClientBuilder.setUserAgent(userAgent);
66
67 Collection<Header> defaultHeaders = new ArrayList<>();
68 defaultHeaders.add(new BasicHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"));
69 httpClientBuilder.setDefaultHeaders(defaultHeaders);
70
71 RequestConfig defaultRequestConfig = RequestConfig.custom()
72 .setSocketTimeout(socketTimeout)
73 .setConnectTimeout(connectTimeout)
74 .setConnectionRequestTimeout(connectionRequestTimeout)
75 .build();
76 httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
77
78 httpClient = httpClientBuilder.build();
79
80 objectMapper = new ObjectMapper();
81 objectMapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
82 }
83
84 public <T> T get(URI uri, Class<T> valueType) throws IOException {
85 return get(uri, new JsonValueReader<>(objectMapper, valueType));
86 }
87
88 public <T> T get(URI uri, TypeReference<T> valueTypeRef) throws IOException {
89 return get(uri, new JsonValueTypeRefReader<>(objectMapper, valueTypeRef));
90 }
91
92 public <T> T get(
93 URI uri,
94 TypeReference<T> valueTypeRef,
95 @Nullable Map<?, ?> params,
96 @Nullable Map<?, ?> headers
97 ) throws IOException {
98 return get(uri, new JsonValueTypeRefReader<>(objectMapper, valueTypeRef), params, headers);
99 }
100
101 public <T> T get(URI uri, ValueReader<T> valueReader) throws IOException {
102 return get(uri, valueReader, null, null);
103 }
104
105 public <T> T get(
106 URI uri,
107 ValueReader<T> valueReader,
108 @Nullable Map<?, ?> params,
109 @Nullable Map<?, ?> headers
110 ) throws IOException {
111 HttpGet httpGet = new HttpGet(buildURI(uri, toNameValuePairs(params)));
112 httpGet.setHeaders(toHeaders(headers));
113 return execute(httpGet, valueReader);
114 }
115
116 public <T> T post(
117 URI uri,
118 Class<T> valueType,
119 @Nullable Map<?, ?> params,
120 @Nullable Map<?, ?> headers,
121 @Nullable Charset charset
122 ) throws IOException {
123 return post(uri, new JsonValueReader<>(objectMapper, valueType),
124 toNameValuePairs(params), toHeaders(headers), charset);
125 }
126
127 public <T> T post(
128 URI uri,
129 TypeReference<T> valueTypeRef,
130 @Nullable Map<?, ?> params,
131 @Nullable Map<?, ?> headers,
132 @Nullable Charset charset
133 ) throws IOException {
134 return post(uri, new JsonValueTypeRefReader<>(objectMapper, valueTypeRef),
135 toNameValuePairs(params), toHeaders(headers), charset);
136 }
137
138 public <T> T post(URI uri, ValueReader<T> valueReader,
139 NameValuePair... params) throws IOException {
140 return post(uri, valueReader, Arrays.asList(params));
141 }
142
143 public <T> T post(URI uri, ValueReader<T> valueReader,
144 List<NameValuePair> params) throws IOException {
145 return post(uri, valueReader, params, null, null);
146 }
147
148 public <T> T post(
149 URI uri,
150 ValueReader<T> valueReader,
151 @Nullable Map<?, ?> params,
152 @Nullable Map<?, ?> headers,
153 @Nullable Charset charset
154 ) throws IOException {
155 return post(uri, valueReader, toNameValuePairs(params), toHeaders(headers), charset);
156 }
157
158 public <T> T post(
159 URI uri,
160 ValueReader<T> valueReader,
161 @Nullable Iterable<? extends NameValuePair> parameters,
162 @Nullable Header[] headers,
163 @Nullable Charset charset
164 ) throws IOException {
165 HttpPost httpPost = new HttpPost(uri);
166 httpPost.setEntity(new UrlEncodedFormEntity(parameters, charset));
167 httpPost.setHeaders(headers);
168 return execute(httpPost, valueReader);
169 }
170
171 public <T> T post(URI uri, ValueReader<T> valueReader, String content,
172 String charset) throws IOException {
173 HttpPost post = new HttpPost(uri);
174 post.setEntity(new StringEntity(content, charset));
175 return execute(post, valueReader);
176 }
177
178 public <T> T post(URI uri, ValueReader<T> valueReader, String content,
179 ContentType contentType) throws IOException {
180 HttpPost post = new HttpPost(uri);
181 post.setEntity(new StringEntity(content, contentType));
182 return execute(post, valueReader);
183 }
184
185 @Deprecated
186 public <T> T execute(
187 final ValueReader<T> valueReader,
188 final HttpUriRequest request) throws IOException {
189 return execute(request, valueReader);
190 }
191
192 public <T> T execute(HttpUriRequest request, ValueReader<T> valueReader) throws IOException {
193 log.debug("Executing: {}", request.getURI());
194 try (CloseableHttpResponse response = httpClient.execute(request)) {
195 return valueReader.read(response);
196 }
197 }
198
199 private URI buildURI(URI uri, @Nullable List<NameValuePair> parameters) throws IllegalArgumentException {
200 URIBuilder builder = new URIBuilder(uri);
201 if (parameters != null) {
202 builder.addParameters(parameters);
203 }
204 try {
205 return builder.build();
206 } catch (URISyntaxException e) {
207 throw new IllegalArgumentException(e);
208 }
209 }
210
211 private List<NameValuePair> toNameValuePairs(@Nullable Map<?, ?> params) {
212 List<NameValuePair> parameters = new ArrayList<>();
213 Optional.ofNullable(params).orElse(emptyMap()).entrySet().stream().forEach(param -> {
214 String name = param.getKey().toString();
215 if (param.getValue() == null) {
216
217 } else if (param.getValue().getClass().isArray()) {
218 Object[] values = (Object[]) param.getValue();
219 Arrays.stream(values).forEach(value -> {
220 parameters.add(new BasicNameValuePair(name, value.toString()));
221 });
222 } else {
223 parameters.add(new BasicNameValuePair(name, param.getValue().toString()));
224 }
225 });
226 return parameters;
227 }
228
229 private Header[] toHeaders(@Nullable Map<?, ?> headers) {
230 return Optional.ofNullable(headers).orElse(emptyMap()).entrySet().stream()
231 .map(header -> new BasicHeader(header.getKey().toString(), header.getValue().toString()))
232 .toArray(Header[]::new);
233 }
234
235
236
237
238 @Override
239 public void close() throws IOException {
240 httpClient.close();
241 }
242
243 }