package com.lcw.util; import com.lcw.eum.RequestMethod; import static com.lcw.eum.RequestMethod.GET; import static com.lcw.eum.RequestMethod.POST; import com.lcw.model.HttpRequestData; import com.sun.webkit.network.CookieManager; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.CookieHandler; import java.net.HttpURLConnection; import java.net.URL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.net.ssl.SSLContext; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.EntityBuilder; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.ssl.SSLContexts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author lancw */ public class HttpClientUtil { public static final String COOKIE = "Cookie"; public static final String REQUEST_HEADER_PREFIX = "request_"; public static CloseableHttpClient CLIENT; private static final CookieStore COOKIE_STORE = new BasicCookieStore(); private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class.getName()); /** * 下载文件 * * @param destUrl * @param fileName * @throws IOException */ public static void downloadFile(String destUrl, String fileName) throws IOException { byte[] buf = new byte[1024]; int size = 0; URL url = new URL(destUrl); HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection(); httpUrl.connect(); try (BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream()); FileOutputStream fos = new FileOutputStream(fileName)) { while ((size = bis.read(buf)) != -1) { fos.write(buf, 0, size); } } httpUrl.disconnect(); } public static HttpResponse sendRequest(HttpRequestData.Request req) throws Exception { Integer timeout = Integer.valueOf(req.getTimeout()); SSLContext sslc = SSLContexts.custom().loadTrustMaterial((X509Certificate[] chain, String authType) -> true).build(); CLIENT = HttpClients.custom().setSSLContext(sslc).setDefaultCookieStore(COOKIE_STORE).setUserAgent(req.getUseagent()).build(); RequestConfig rc = RequestConfig.custom().setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).setRedirectsEnabled(true).build(); switch (RequestMethod.valueOf(req.getMethod())) { case GET: return doGet(req, rc); case POST: return doPost(req, rc); } return null; } private static HttpResponse doGet(HttpRequestData.Request req, RequestConfig rc) throws Exception { String url = req.getUrlWithData(); LOGGER.info("Get request url:" + url); HttpGet get = new HttpGet(url); get.setConfig(rc); get.setHeader("Content-Type", req.getContentType() + ";charset=" + req.getCharset()); initHeader(get, req.getHeader()); HttpClientContext hc = new HttpClientContext(); HttpResponse resp = CLIENT.execute(get, hc); addResquestHeaderToResponseForShow(resp, hc.getRequest()); return resp; } private static HttpResponse doPost(HttpRequestData.Request req, RequestConfig rc) throws Exception { String url = req.getUrl(); List<NameValuePair> parameters = new ArrayList<>(); String bd = req.encodeBody(); HttpEntity formEntiry = null; if (bd != null) { String ct = req.getContentType(); ContentType type = ContentType.create(ct, req.getCharset()); if (ct.contains("xml") || ct.contains("json") || ContentType.TEXT_PLAIN.getMimeType().equals(ct)) { StringEntity se = new StringEntity(bd, req.getCharset()); se.setContentType(ct); formEntiry = se; } else if (com.lcw.eum.ContentType.CONTENT_TYPE_MULTIPART_FORM_DATA.getCode().equals(ct)) { String[] tmp = bd.split("&"); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); for (String str : tmp) { int idx = str.indexOf("="); if (idx > 0) { String t0 = str.substring(0, idx); String t1 = str.substring(idx + 1); if (t1.startsWith("/") || t1.substring(1).startsWith(":")) { File file = new File(t1); if (file.exists()) { builder.addBinaryBody(t0, file); LOGGER.info("文件字段提交:" + str); } else { builder.addTextBody(t0, t1); LOGGER.info("文件不存在或误判断为文件,转为普通字段提交:" + str); } } else { builder.addTextBody(t0, t1); } } else { throw new Exception("错误参数:" + str); } } formEntiry = builder.build(); } else { String[] tmp = bd.split("&"); for (String str : tmp) { int idx = str.indexOf("="); if (idx > 0) { parameters.add(new BasicNameValuePair(str.substring(0, idx), str.substring(idx + 1))); } else { throw new Exception("错误参数:" + str); } } formEntiry = EntityBuilder.create().setParameters(parameters).setContentType(type).build(); } } return sendPostHttp(url, formEntiry, req.getHeader(), rc); } private static HttpResponse sendPostHttp(String url, HttpEntity formEntiry, String header, RequestConfig rc) throws Exception { HttpPost postmethod = new HttpPost(url); postmethod.setConfig(rc); initHeader(postmethod, header); postmethod.setEntity(formEntiry); HttpClientContext hc = new HttpClientContext(); HttpResponse resp = CLIENT.execute(postmethod, hc); addResquestHeaderToResponseForShow(resp, hc.getRequest()); return resp; } private static void initHeader(HttpRequestBase base, String header) throws Exception { if (header != null && !header.trim().isEmpty()) { String[] tmp = header.split("&"); for (String str : tmp) { if (str.startsWith(COOKIE)) { base.addHeader(COOKIE, str.replace(COOKIE + "=", "")); } else { int idx = str.indexOf("="); if (idx > 0) { base.addHeader(str.substring(0, idx), str.substring(idx + 1)); } } } } CookieManager cm = (CookieManager) CookieHandler.getDefault(); Field fd = cm.getClass().getDeclaredField("store"); fd.setAccessible(true); Object cs = fd.get(cm);//cookieStore fd = cs.getClass().getDeclaredField("buckets"); fd.setAccessible(true); cs = fd.get(cs);//Map<String,Map<Cookie,Cookie>> Method md = cs.getClass().getDeclaredMethod("get", Object.class); String domain = base.getURI().getHost(); Map map = new HashMap(); while (domain.length() > 0) { Object bucket = md.invoke(cs, domain); if (bucket != null) { map.putAll((Map) bucket); } int nextPoint = domain.indexOf('.'); if (nextPoint != -1) { domain = domain.substring(nextPoint + 1); } else { break; } } if (!map.isEmpty()) { Iterator it = map.keySet().iterator(); StringBuilder sb = new StringBuilder(); while (it.hasNext()) { Object next = it.next(); fd = next.getClass().getDeclaredField("name"); fd.setAccessible(true); sb.append(fd.get(next)); fd = next.getClass().getDeclaredField("value"); fd.setAccessible(true); sb.append("=").append(fd.get(next)).append(";"); } if (!sb.toString().isEmpty()) { Header h = base.getFirstHeader(COOKIE); String ck = ""; if (h != null) { ck = h.getValue(); } base.addHeader(COOKIE, sb.toString() + ck); } } } private static void addResquestHeaderToResponseForShow(HttpResponse resp, HttpRequest base) throws Exception { Header[] hs = base.getAllHeaders(); if (hs != null) { for (Header h : hs) { resp.addHeader(REQUEST_HEADER_PREFIX + h.getName(), h.getValue()); } } } }