HttpClientTemplate JDK11以上的版本,可以用,我写的。

这一生的挚爱 提交于 2020-03-07 11:51:00
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();
    }

}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!