HttpGet请求测试代码
public class HttpGetTest{ public static void main(String[] args) throws IOException { //实例化HttpClient实例 CloseableHttpClient client = HttpClients.createDefault(); //请求url String url = "https://www.baidu.com"; HttpGet httpGet = new HttpGet(url); //添加请求头 httpGet.addHeader("Content-Type", "application/json"); httpGet.addHeader("Accept", "application/json"); //发起请求 CloseableHttpResponse response = client.execute(httpGet); //获得请求状态码 int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200) { //获得请求实体 HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity, "utf-8"); System.out.println(result); //获得所有请求头 Header[] allHeaders = response.getAllHeaders(); for (Header header : allHeaders) { //请求头名称 String name = header.getName(); //请求头值 String value = header.getValue(); System.out.println(name + ":" + value); } } } }HttpPost请求
package fmx.test.httptest; import net.sf.json.JSONObject; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; /** * @author fmx * @version 1.0 * @date 2020/9/3 22:40 */ public class HttpPostTest { public static void main(String[] args) throws IOException { //实例化HttpClient实例 CloseableHttpClient client = HttpClients.createDefault(); //请求url String url = "https://www.baidu.com"; HttpPost httpPost = new HttpPost(url); //添加请求头 httpPost.addHeader("Content-Type", "application/json"); httpPost.addHeader("Accept", "application/json"); //请求数据 Map<String, Object> map = new HashMap<>(); JSONObject x = JSONObject.fromObject(map); String body = x.toString(); StringEntity strEntity = new StringEntity(body, Charset.forName("UTF-8")); strEntity.setContentType("application/json"); httpPost.setEntity(strEntity); //设置超时时间按 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(80000).setConnectTimeout(80000).build(); httpPost.setConfig(requestConfig); //发起请求 CloseableHttpResponse response = client.execute(httpPost); //获得请求状态码 int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200) { //获得请求实体 HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity, "utf-8"); System.out.println(result); //获得所有请求头 Header[] allHeaders = response.getAllHeaders(); for (Header header : allHeaders) { //请求头名称 String name = header.getName(); //请求头值 String value = header.getValue(); System.out.println(name + ":" + value); } } } } 接收请求(以微信支付回调为例) @PostMapping("/payNotify") public JSONObject wxNotify(HttpServletRequest request, HttpServletResponse response, @RequestHeader HttpHeaders headers) { //返回通知的应答报文,code(32):SUCCESS为清算机构接收成功;message(64):错误原因 JSONObject responseJson = new JSONObject(); responseJson.put("code", "FAIL"); //支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); if (!headers.containsKey("Wechatpay-Serial") || !headers.containsKey("Wechatpay-Timestamp") || !headers.containsKey("Wechatpay-Nonce") || !headers.containsKey("Wechatpay-Signature")) { log.info("请求头丢失"); responseJson.put("message", "回调请求header缺失"); return responseJson; } String wechatpaySerial = headers.getFirst("Wechatpay-Serial");//平台证书序列号 String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp");//应答时间戳 String wechatpayNonce = headers.getFirst("Wechatpay-Nonce");//应答随机串 String wechatpaySignature = headers.getFirst("Wechatpay-Signature"); //应答签名 if (!MyWxPayConfig.WECHAT_CERTIFICATR_SERIAL_NO.equals(wechatpaySerial)) { responseJson.put("message", "回调请求证书序列化不一致"); return responseJson; } log.info("WechatpaySignature{}", wechatpaySerial); log.info("WechatpayTimestamp{}", wechatpayTimestamp); log.info("WechatpayNonce{}", wechatpayNonce); log.info("WechatpaySignature{}", wechatpaySignature); try { //获取微信POST过来反馈信息 Map<String, String> params = new HashMap<String, String>(); // post请求的密文数据 ServletInputStream in = request.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String sReqData = ""; String itemStr = "";//作为输出字符串的临时串,用于判断是否读取完毕 while (null != (itemStr = reader.readLine())) { sReqData += itemStr; } log.info("resultData{}", sReqData); //验签 byte[] signature = null; try { signature = Base64.getDecoder().decode(wechatpaySignature); } catch (Exception e) { e.printStackTrace(); log.info("响应签名Base64解码失败"); responseJson.put("message", "响应签名Base64解码失败"); return responseJson; } boolean verify = WxPayUtils.verify(wechatpayTimestamp, wechatpayNonce, sReqData, signature); if (!verify) { log.info("回调信息签名验证失败"); responseJson.put("message", "回调信息签名验证失败"); return responseJson; } JSONObject jsonObject = JSONObject.fromObject(sReqData); Map<String, Object> m = (Map) jsonObject; if (m.get("event_type") == null || !m.get("event_type").equals("TRANSACTION.SUCCESS")) { //补充处理部分 response.setStatus(HttpServletResponse.SC_OK); responseJson.put("code", "SUCCESS"); responseJson.put("message", "微信支付失败,商户处理成功"); } String resource = m.get("resource").toString(); JSONObject resourcejso = JSONObject.fromObject(resource); Map<Object, Object> mm = (Map) resourcejso; String nonce = mm.get("nonce").toString(); String ciphertext = mm.get("ciphertext").toString(); String assc = mm.get("associated_data").toString(); String APIv3Key = MyWxPayConfig.API_V3_KEY; //解密回调信息 byte[] key = APIv3Key.getBytes("UTF-8"); WxAPIV3AesUtil aesUtil = new WxAPIV3AesUtil(key); String decryptToString = aesUtil.decryptToString(assc.getBytes("UTF-8"), nonce.getBytes("UTF-8"), ciphertext); JSONObject decryption = JSONObject.fromObject(decryptToString); Map<String, Object> decryptionMap = (Map) decryption; System.out.println(decryptionMap); if (decryptionMap.get("transaction_id") == null) { log.info("未接受到微信订单号"); responseJson.put("message", "微信支付成功,未接受到微信订单号"); return responseJson; } if (decryptionMap.get("out_trade_no") == null) { log.info("未接收到商家订单号"); responseJson.put("message", "微信支付成功,未接收到商家订单号"); return responseJson; } String outTradeNo = decryptionMap.get("out_trade_no").toString(); List<Integer> status = partyPaymentRecordService.getPaymentStatusByoutTradeNo(outTradeNo); boolean flag = false; if (status != null) { for (Integer sta : status) { if (sta != null && sta != 0) { flag = true; break; } } } if (flag) { response.setStatus(HttpServletResponse.SC_OK); responseJson.put("code", "SUCCESS"); responseJson.put("message", "微信支付成功"); return responseJson; } // statusCode decryptionMap.put("statusCode", "200"); partyPaymentRecordService.trackOrder(decryptionMap, null); System.out.println(decryptToString); } catch (Exception e) { e.printStackTrace(); } log.info("微信支付成功"); response.setStatus(HttpServletResponse.SC_OK); responseJson.put("code", "SUCCESS"); responseJson.put("message", "微信支付成功"); return responseJson; } } 若在开发环境中,则需交给spring管理 import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource(value = "classpath:/properties/httpClient.properties") public class HttpClientConfig { @Value("${http.maxTotal}") private Integer maxTotal; //最大连接数 @Value("${http.defaultMaxPerRoute}") private Integer defaultMaxPerRoute; //最大并发链接数 @Value("${http.connectTimeout}") private Integer connectTimeout; //创建链接的最大时间 @Value("${http.connectionRequestTimeout}") private Integer connectionRequestTimeout; //链接获取超时时间 @Value("${http.socketTimeout}") private Integer socketTimeout; //数据传输最长时间 @Value("${http.staleConnectionCheckEnabled}") private boolean staleConnectionCheckEnabled; //提交时检查链接是否可用 //定义httpClient链接池 @Bean(name = "httpClientConnectionManager") public PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager() { PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); manager.setMaxTotal(maxTotal); //设定最大链接数 manager.setDefaultMaxPerRoute(defaultMaxPerRoute); //设定并发链接数 return manager; } //定义HttpClient /** * 实例化连接池,设置连接池管理器。 * 这里需要以参数形式注入上面实例化的连接池管理器 * * @Qualifier 指定bean标签进行注入 */ @Bean(name = "httpClientBuilder") public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) { //HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(httpClientConnectionManager); return httpClientBuilder; } /** * 注入连接池,用于获取httpClient * * @param httpClientBuilder * @return */ @Bean public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) { return httpClientBuilder.build(); } /** * Builder是RequestConfig的一个内部类 * 通过RequestConfig的custom方法来获取到一个Builder对象 * 设置builder的连接信息 * * @return */ @Bean(name = "builder") public RequestConfig.Builder getBuilder() { RequestConfig.Builder builder = RequestConfig.custom(); return builder.setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setSocketTimeout(socketTimeout) .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled); } /** * 使用builder构建一个RequestConfig对象 * * @param builder * @return */ @Bean public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) { return builder.build(); } } import javax.annotation.PreDestroy; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.pool.PoolStats; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component //交给spring容器管理 public class HttpClientClose extends Thread { @Autowired private PoolingHttpClientConnectionManager manage; private volatile boolean shutdown; //开关 volatitle表示多线程可变数据,一个线程修改,其他线程立即修改 public HttpClientClose() { ///System.out.println("执行构造方法,实例化对象"); //线程开启启动 this.start(); } @Override public void run() { try { //如果服务没有关闭,执行线程 while (!shutdown) { synchronized (this) { wait(5000); //等待5秒 //System.out.println("线程开始执行,关闭超时链接"); //关闭超时的链接 PoolStats stats = manage.getTotalStats(); int av = stats.getAvailable(); //获取可用的线程数量 int pend = stats.getPending(); //获取阻塞的线程数量 int lea = stats.getLeased(); //获取当前正在使用的链接数量 int max = stats.getMax(); //System.out.println("max/"+max+": av/"+av+": pend/"+pend+": lea/"+lea); manage.closeExpiredConnections(); } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } super.run(); } //关闭清理无效连接的线程 @PreDestroy //容器关闭时执行该方法. public void shutdown() { shutdown = true; synchronized (this) { //System.out.println("关闭全部链接!!"); notifyAll(); //全部从等待中唤醒.执行关闭操作; } } }httpClient.properties
#最大连接数 http.maxTotal = 1000 #并发数 http.defaultMaxPerRoute = 20 #创建连接的最长时间 http.connectTimeout=5000 #从连接池中获取到连接的最长时间 http.connectionRequestTimeout=500 #数据传输的最长时间 http.socketTimeout=5000 #提交请求前测试连接是否可用 http.staleConnectionCheckEnabled=true 调用API import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @Service public class HttpClientService { @Autowired private CloseableHttpClient httpClient; @Autowired private RequestConfig requestConfig; /** * 编辑工具API的目的简化代码,实现松耦合 * 作用:帮助用户发起http请求,获取正确的结果返回给用户 参数设计: * 1.用户url地址 * 2.Map<参数名,参数值 > 3.字符集 * * get请求方式: 1.无参数时:http://www.baidu.com * 2.有参数时:http://www.baidu.com?key=-- * * @param url * @param params * @param charset * @return */ // 实现httpClient GET提交 public String doGet(String url, Map<String, String> params, String charset) { String result = null; // 1.判断字符集编码是否为空 如果为空则给定默认值utf-8 if (StringUtils.isEmpty(charset)) { charset = "UTF-8"; } // 2.判断用户是否需要传递参数 if (params != null) { try { URIBuilder uriBuilder = new URIBuilder(url); for (Map.Entry<String, String> entry : params.entrySet()) { uriBuilder.addParameter(entry.getKey(), entry.getValue()); } // url?id=1&name=tom url = uriBuilder.build().toString(); } catch (Exception e) { e.printStackTrace(); } } // 3.定义参数提交对象 HttpGet get = new HttpGet(url); // 4.为请求设定超时时间 get.setConfig(requestConfig); // 5.通过httpClient发送请求 try { CloseableHttpResponse response = httpClient.execute(get); if (response.getStatusLine().getStatusCode() == 200) { // 表示程序调用成功 result = EntityUtils.toString(response.getEntity(), charset); } else { System.out.println("调用异常:状态信息:" + response.getStatusLine().getStatusCode()); throw new RuntimeException(); } } catch (Exception e) { e.printStackTrace(); } return result; } public String doGet(String url) { return doGet(url, null, null); } public String doGet(String url, Map<String, String> params) { return doGet(url, params, null); } public String doGet(String url, String charset) { return doGet(url, null, charset); } // 实现httpClient POST提交 public String doPost(String url, Map<String, String> params, String charset) { String result = null; // 1.定义请求类型 HttpPost post = new HttpPost(url); post.setConfig(requestConfig); // 定义超时时间 // 2.判断字符集是否为null if (StringUtils.isEmpty(charset)) { charset = "UTF-8"; } // 3.判断用户是否传递参数 if (params != null) { // 3.2准备List集合信息 List<NameValuePair> parameters = new ArrayList<>(); // 3.3将数据封装到List集合中 for (Map.Entry<String, String> entry : params.entrySet()) { parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } // 3.1模拟表单提交 try { UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, charset); // 采用u8编码 // 3.4将实体对象封装到请求对象中 post.setEntity(formEntity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // 4.发送请求 try { CloseableHttpResponse response = httpClient.execute(post); // 4.1判断返回值状态 if (response.getStatusLine().getStatusCode() == 200) { // 4.2表示请求成功 result = EntityUtils.toString(response.getEntity(), charset); } else { System.out.println("获取状态码信息:" + response.getStatusLine().getStatusCode()); throw new RuntimeException(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } public String doPost(String url) { return doPost(url, null, null); } public String doPost(String url, Map<String, String> params) { return doPost(url, params, null); } public String doPost(String url, String charset) { return doPost(url, null, charset); } }