HttpClientUtilsParameterizedTypeUtils
HttpClientUtilsimport com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import lombok.Data; import lombok.SneakyThrows; import org.apache.http.Header; import org.apache.http.HeaderIterator; import org.apache.http.HttpEntity; import org.apache.http.StatusLine; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.*; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustAllStrategy; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import org.apache.http.util.TextUtils; import javax.net.ssl.SSLContext; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlRootElement; import java.io.StringReader; import java.lang.reflect.ParameterizedType; import java.nio.charset.Charset; import java.util.*; public class HttpClientUtils { private static final int CONNECT_TIMEOUT = 8000; private static final int SOCKET_TIMEOUT = 8000; private static final int MAX_TOTAL = 512; private static final int MAX_PER_ROUTE = 32; private static final String CONTENT_TYPE = "Content-Type"; private static final String USER_AGENT = "User-Agent"; private static final String DEFAULT_CHARSET = "UTF-8"; private static final String TEXT$ = "text"; private static final String JSON$ = "json"; private static final String XML$ = "xml"; private static final String EMPTY = ""; // region HttpRequest part private static HttpUriRequest createRequestbase(String url, String method) { HttpUriRequest request = null; switch (Objects.nonNull(method) ? method.toUpperCase() : EMPTY) { case HttpGet.METHOD_NAME: request = new HttpGet(url); break; case HttpPost.METHOD_NAME: request = new HttpPost(url); break; case HttpPut.METHOD_NAME: request = new HttpPut(url); break; case HttpPatch.METHOD_NAME: request = new HttpPatch(url); break; case HttpDelete.METHOD_NAME: request = new HttpDelete(url); break; case HttpHead.METHOD_NAME: request = new HttpHead(url); break; case HttpOptions.METHOD_NAME: request = new HttpOptions(url); break; } return request; } private static void createRequestHeaders(HttpUriRequest request, HttpHeaders requestHead) { if (Objects.nonNull(request)) { if (Objects.nonNull(requestHead) && !requestHead.isEmpty()) { requestHead.forEach((k, v) -> request.setHeader(k, requestHead.getFirst(k))); } else { request.setHeader(CONTENT_TYPE, "application/json"); } request.setHeader(USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0"); } } private static void createRequestBody(HttpUriRequest request, HttpEntity requestBody) { if (Objects.nonNull(request) && (request instanceof HttpEntityEnclosingRequestbase)) { ((HttpEntityEnclosingRequestbase) request).setEntity(requestBody); } } // endregion HttpRequest // region HttpResponse part @Data public static class HttpStatus { int value; String reasonPhrase; } public static class HttpHeaders extends HashMapParameterizedTypeUtils> { public String getFirst(String headerName) { List headerValues = super.get(headerName); return headerValues != null ? headerValues.get(0) : null; } public void add(String headerName, String headerValue) { super.computeIfAbsent(headerName, (k) -> new linkedList<>()).add(headerValue); } public void addAll(String headerName, List extends String> headerValues) { super.computeIfAbsent(headerName, (k) -> new linkedList<>()).addAll(headerValues); } public void addAll(Map > values) { values.forEach(this::addAll); } public void set(String headerName, String headerValue) { List headerValues = new linkedList<>(); headerValues.add(headerValue); super.put(headerName, headerValues); } public void setAll(Map values) { values.forEach(this::set); } public Map toSinglevalueMap() { linkedHashMap singlevalueMap = new linkedHashMap<>(super.size()); super.forEach((key, valueList) -> singlevalueMap.put(key, valueList.get(0))); return singlevalueMap; } public ContentType getContentType() { String value = this.getFirst(CONTENT_TYPE); return TextUtils.isBlank(value) ? null : ContentType.parse(value); } } @Data public static class ResponseEntity { HttpStatus status; HttpHeaders headers; Object body; public boolean hasBody() { return null != this.body; } String getMimeType() { if (Objects.nonNull(headers)) { ContentType contentType = headers.getContentType(); if (Objects.nonNull(contentType)) { String mimeType = contentType.getMimeType(); if (Objects.nonNull(mimeType)) { return mimeType; } } } return EMPTY; } Charset getCharset() { if (Objects.nonNull(headers)) { ContentType contentType = headers.getContentType(); if (Objects.nonNull(contentType)) { Charset charset = contentType.getCharset(); if (Objects.nonNull(charset)) { return charset; } } } return Charset.forName(DEFAULT_CHARSET); } } private static void createResponseHeaders(ResponseEntity response, HeaderIterator iterator) { if (Objects.nonNull(response) && Objects.nonNull(iterator)) { HttpHeaders headers = new HttpHeaders(); while (iterator.hasNext()) { final Header header = iterator.nextHeader(); headers.add(header.getName(), header.getValue()); } response.setHeaders(headers); } } private static void createResponseStatus(ResponseEntity response, StatusLine statusLine) { if (Objects.nonNull(response) && Objects.nonNull(statusLine)) { HttpStatus status = new HttpStatus(); status.setValue(statusLine.getStatusCode()); status.setReasonPhrase(statusLine.getReasonPhrase()); response.setStatus(status); } } // endregion HttpResponse // region MessageConverter part @SuppressWarnings("unchecked") @SneakyThrows private static T parseObjectFromXMLString(String xml, ParameterizedType type) { if (!TextUtils.isBlank(xml) && Objects.nonNull(type)) { Class>[] classes = ParameterizedTypeUtils.getClasses(type); if (classes.length == 0 || (classes.length == 1 && String.class == classes[0])) { return (T) xml; } JAXBContext context = JAXBContext.newInstance(classes); Unmarshaller um = context.createUnmarshaller(); return (T) um.unmarshal(new StringReader(xml)); } return null; } private static T parseObjectFromJSONString(String json, ParameterizedType type) { if (ParameterizedTypeUtils.hasActualTypeArguments(type)) { return JSON.parseObject(json, type); } else { Class clazz = ParameterizedTypeUtils.getClass(type); return JSON.parseObject(json, clazz); } } private static String toJSONString(Object obj) { return JSON.toJSONString(obj); } // endregion MessageConverter @SneakyThrows private static CloseableHttpClient getCustomHttpClient() { RequestConfig reqCfg = RequestConfig.custom() .setSocketTimeout(SOCKET_TIMEOUT) .setConnectTimeout(CONNECT_TIMEOUT) .build(); SocketConfig sockCfg = SocketConfig.custom() .setTcpNoDelay(true) .setSoTimeout(SOCKET_TIMEOUT) .build(); SSLContext sslCtx = SSLContexts.custom() .loadTrustMaterial(TrustAllStrategy.INSTANCE) .build(); Registry registry = RegistryBuilder. create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", new SSLConnectionSocketFactory(sslCtx, NoopHostnameVerifier.INSTANCE)) .build(); PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(registry); manager.setMaxTotal(MAX_TOTAL); manager.setDefaultMaxPerRoute(MAX_PER_ROUTE); HttpClientBuilder builder = HttpClients.custom(); builder.setDefaultRequestConfig(reqCfg); builder.setDefaultSocketConfig(sockCfg); builder.setConnectionManager(manager); builder.setRetryHandler(new DefaultHttpRequestRetryHandler(1, true)); return builder.build(); } private static ResponseEntity exchange(String url, String method, HttpEntity requestBody, HttpHeaders requestHead) { ResponseEntity ret = new ResponseEntity(); HttpUriRequest request = createRequestbase(url, method); if (Objects.nonNull(request)) { createRequestHeaders(request, requestHead); createRequestBody(request, requestBody); try (CloseableHttpClient httpClient = getCustomHttpClient(); CloseableHttpResponse response = httpClient.execute(request)) { final StatusLine statusLine = response.getStatusLine(); createResponseStatus(ret, statusLine); final HeaderIterator headerIterator = response.headerIterator(); createResponseHeaders(ret, headerIterator); final HttpEntity responseEntity = response.getEntity(); if (Objects.nonNull(responseEntity)) { ret.setBody(EntityUtils.toByteArray(responseEntity)); } } catch (Throwable ex) { throw new RuntimeException(ex); } } return ret; } @SuppressWarnings("unchecked") public static T fetch(String url, String method, HttpEntity body, HttpHeaders headers, ParameterizedType parameterizedType) { ResponseEntity responseEntity = exchange(url, method, body, headers); if (!responseEntity.hasBody()) { return null; } Class clazz = ParameterizedTypeUtils.getClass(parameterizedType); final Object responseEntityBody = responseEntity.getBody(); if (Objects.equals(clazz, responseEntityBody.getClass())) { return (T) responseEntityBody; } final String mime = responseEntity.getMimeType().toLowerCase(); boolean isJson = mime.contains(JSON$), isXml = mime.contains(XML$), isText = mime.contains(TEXT$); String data; if (isJson || isXml || isText) { data = new String((byte[]) responseEntityBody, responseEntity.getCharset()); if (isXml && Objects.nonNull(clazz.getDeclaredAnnotation(XmlRootElement.class))) { return parseObjectFromXMLString(data, parameterizedType); } return parseObjectFromJSONString(data, parameterizedType); } data = toJSONString(responseEntityBody); return parseObjectFromJSONString(data, parameterizedType); } public static T fetch(String url, String method, HttpEntity body, HttpHeaders headers, TypeReference responseType) { ParameterizedType parameterizedType = ParameterizedTypeUtils.make(responseType); return fetch(url, method, body, headers, parameterizedType); } public static T fetch(String url, String method, HttpEntity body, HttpHeaders headers, Class clazz) { ParameterizedType parameterizedType = ParameterizedTypeUtils.make(clazz); return fetch(url, method, body, headers, parameterizedType); } }
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.util.ParameterizedTypeImpl; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Objects; public class ParameterizedTypeUtils { public static ParameterizedType make(TypeReference> typeReference) { return (ParameterizedType) typeReference.getType(); } public static ParameterizedType make(Type rawType) { return make(rawType, null, null); } public static ParameterizedType make(Type rawType, Type[] actualTypeArguments) { return make(rawType, actualTypeArguments, null); } public static ParameterizedType make(Type rawType, Type[] actualTypeArguments, Type ownerType) { // sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(Class>, Type[], Type); return new ParameterizedTypeImpl(actualTypeArguments, ownerType, rawType); } public static Type getRawType(ParameterizedType parameterizedType) { return parameterizedType.getRawType(); } public static Type getOwnerType(ParameterizedType parameterizedType) { return parameterizedType.getOwnerType(); } public static Type[] getActualTypeArguments(ParameterizedType parameterizedType) { Type[] argTypes = parameterizedType.getActualTypeArguments(); if (Objects.isNull(argTypes)) { argTypes = new Type[0]; } return argTypes; } public static boolean hasRawType(ParameterizedType parameterizedType) { return Objects.nonNull(getRawType(parameterizedType)); } public static boolean hasOwnerType(ParameterizedType parameterizedType) { return Objects.nonNull(getOwnerType(parameterizedType)); } public static boolean hasActualTypeArguments(ParameterizedType parameterizedType) { return getActualTypeArguments(parameterizedType).length > 0; } @SuppressWarnings("unchecked") public staticClass getClass(ParameterizedType parameterizedType) { return (Class ) parameterizedType.getRawType(); } public static Class>[] getClasses(ParameterizedType parameterizedType) { Type[] typeArgs = getActualTypeArguments(parameterizedType); Class>[] classes = new Class[typeArgs.length + 1]; classes[0] = getClass(parameterizedType); Type item; for (int i = 0, cnt = typeArgs.length; i < cnt; i++) { item = typeArgs[i]; classes[i + 1] = (item instanceof ParameterizedType ? getClass((ParameterizedType) item) : (Class>) item); } return classes; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)