package com.diandaxia.common.template; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.IOException; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.Charset; import java.util.Map; /** * Spring的restTemplate不好用 by liyuxin * 自己封装一个使用,以下是restTemplate的发送post请求的用法。必须得用这个MultiValueMap 否则controller 层接收不到参数。 * 解决方法1:在controller 那里增加@RequestBody 注解,但是这么做就污染了此controller 只能接收 restTemplate的提交. * 解决方法2:在url上像get请求一样拼接占位符,然后把参数的值放在第四个变量上。这种做法也不好。。 * 具体参见:https://blog.csdn.net/weixin_40461281/article/details/83472648 * MultiValueMap<String, Object> postMap = new LinkedMultiValueMap<String, Object>(); * postMap.add("code", code); * postMap.add("state", state); * ResponseUtil responseUtil = restTemplateBuilder.build().postForObject(oauthUrl, postMap, ResponseUtil.class); * if (!responseUtil.getFlag()){ * oauthResultBean.setFlag(false); * oauthResultBean.setMsg(responseUtil.getMsg()); * return oauthResultBean; * } * ---------------------------------------- * 决定自己写个简单的,方便自己使用,内部用到了ObjectMapper,尽量不要static了,所以交给Spring来管理内存吧 */ @Component public class HttpClientTemplate { @Autowired ObjectMapper objectMapper; /** * 发送GET请求,响应是数据,默认用UTF-8编码来读取 */ public String httpGet(String getUrl, Map<String, String> paramsMap) throws IOException, InterruptedException { /** * 1.判断是否有入参,有的话从Map中取值拼接,注意需要UrlEncode */ String paramsStr = null; StringBuilder stringBuilder = new StringBuilder(); if (paramsMap != null){ for (String key : paramsMap.keySet()){ stringBuilder.append(key).append("=").append(URLEncoder.encode(paramsMap.get(key), Charset.forName("UTF-8"))).append("&"); } paramsStr = stringBuilder.deleteCharAt(stringBuilder.length()-1).toString(); } if(paramsStr != null){ getUrl = getUrl.concat("?").concat(paramsStr); } /** * 2.开始get请求,返回的结果用UTF-8编码读取 */ HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create(getUrl)).GET().build(); HttpResponse<String> httpResponse = HttpClient.newBuilder().build().send(httpRequest, HttpResponse.BodyHandlers.ofString(Charset.forName("UTF-8"))); return httpResponse.body(); } /** * 发送Post请求 * 设置 Content-Type 为:application/x-www-form-urlencoded(经过测试必须设置,那就设置把) * 1.POST请求的两种编码格式:application/x-www-urlencoded是浏览器默认的编码格式,用于键值对参数,参数之间用&间隔; * 2.multipart/form-data常用于文件等二进制,也可用于键值对参数,最后连接成一串字符传输(参考Java OK HTTP)。除了这两个编码格式,还有application/json也经常使用。 */ public String httpPostByForm(String postUrl, Map<String, String> paramsMap) throws IOException, InterruptedException { /** * 1.拼接参数与get请求一样 */ String paramsStr = null; StringBuilder stringBuilder = new StringBuilder(); if (paramsMap != null){ for (String key : paramsMap.keySet()){ stringBuilder.append(key).append("=").append(URLEncoder.encode(paramsMap.get(key), Charset.forName("UTF-8"))).append("&"); } paramsStr = stringBuilder.deleteCharAt(stringBuilder.length()-1).toString(); } /** * 2.开始提交post请求 */ HttpRequest httpRequest = null; if(paramsStr != null){ httpRequest = HttpRequest.newBuilder().uri(URI.create(postUrl)).setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8").POST(HttpRequest.BodyPublishers.ofString(paramsStr, Charset.forName("UTF-8"))).build(); }else { httpRequest = HttpRequest.newBuilder().uri(URI.create(postUrl)).POST(HttpRequest.BodyPublishers.noBody()).build(); } HttpResponse<String> httpResponse = HttpClient.newBuilder().build().send(httpRequest, HttpResponse.BodyHandlers.ofString(Charset.forName("UTF-8"))); return httpResponse.body(); } /** * 有些服务端规定, Content-Type 必须为:Content-Type:application/json * 如拼多多的授权获取token那里必须post提交,且Header 必须设置:Content-Type:application/json * 请求报文内容必须为JSON格式报文包 */ public String httpPostByJson(String postUrl, Map<String, String> paramsMap) throws IOException, InterruptedException { /** * 1.转换成json报文 */ String paramsJson = null; if (paramsMap.size() != 0){ paramsJson = objectMapper.writeValueAsString(paramsMap); } /** * 2.开始提交post请求 */ HttpRequest httpRequest = null; if(paramsJson != null){ httpRequest = HttpRequest.newBuilder().uri(URI.create(postUrl)).setHeader("Content-Type", "application/json;charset=UTF-8").POST(HttpRequest.BodyPublishers.ofString(paramsJson, Charset.forName("UTF-8"))).build(); }else { httpRequest = HttpRequest.newBuilder().uri(URI.create(postUrl)).POST(HttpRequest.BodyPublishers.noBody()).build(); } HttpResponse<String> httpResponse = HttpClient.newBuilder().build().send(httpRequest, HttpResponse.BodyHandlers.ofString(Charset.forName("UTF-8"))); return httpResponse.body(); } }