HttpClient使用详解

前言:

在工作中我们会经常碰到调用别的系统接口的问题,如果是http接口的话,我们一般会选择使用HttpClient的来进行接口的调用。这篇文章就讲解下如何使用HttpClient调用别人的接口,主要从两个方面,第一种参数是map格式(post,get请求),第二种参数是json格式(psot,get请求)来展开讲解。

正文:

一、什么是HttpClient?

百度百科解释:HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

通俗的解释:HttpClinet是以编程的方式(代码方式)模拟浏览器对接口进行访问从而进行数据的交互的工具包。

二、在什么场景下需要使用HttpClient?

1.需要调用其他系统接口时,尤其是基于HTTP协议的接口(我个人这种场景下使用HttpClient最多)

2.调用WebService接口(个人觉得不是特别好用)

三、为什么要使用HttpClient?

HttpClient实际上是对Java提供方法的一些封装,而HttpURLConnection是java的标准类,什么也没封装,用起来太原始,不方便。例如:在HttpURLConnection中的输入输出流操作,但是在HttpClient被统一封装成了HttpPost(HttpGet)和HttpResponse,这样就就减少了操作的繁琐性。可以类比,jdbc就相当于HttpURLConnection,MyBatis就相当于HttpClient。

四、怎么使用HttpClient?

1.使用方法:

①创建 HttpClient 的实例

②创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

③如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。

④调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

⑤调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

⑥ 释放连接。无论执行方法是否成功,都必须释放连接

2.Demo1:HttpClient模拟浏览器get请求,请求接口,参数格式类似于form表单的get形式(这里HttpClient版本是4.5.5)

maven依赖:


   org.apache.httpcomponents
   httpclient
   4.5.5


   org.apache.httpcomponents
   httpmime
   4.5.5

调用方代码(封装的HttpClient工具类的方法):

@Slf4j
public class HttpClientUtil {
    private final static transient Log logger = LogFactory.getLog(HttpClientUtil.class);

    public static final String CHARSET = "UTF-8";
    public static final int CONNECT_TIMEOUT = 10 * 1000;

    private static CloseableHttpClient httpClient;

    static {
        RequestConfig config = RequestConfig.custom()
                .setConnectionRequestTimeout(CONNECT_TIMEOUT)//从连接池中获取可用连接最大超时时间
                .setConnectTimeout(CONNECT_TIMEOUT)//连接目标url最大超时
                .setSocketTimeout(CONNECT_TIMEOUT).build();//等待响应(读数据)最大超时
        //创建HttpClient实例
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }


    public static String doGet(String url, Map params,
                               String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {//组装参数和url
            if (params != null && !params.isEmpty()) {
                List pairs = new ArrayList(
                        params.size());
                for (Map.Entry entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?"
                        + EntityUtils.toString(new UrlEncodedFormEntity(pairs,
                        charset));
            }
            HttpGet httpGet = new HttpGet(url);//创建HttpGET
            CloseableHttpResponse response = httpClient.execute(httpGet);//执行HttpGet请求
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :"
                        + statusCode);
            }
            HttpEntity entity = response.getEntity();//获取响应的结果
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");//格式化响应的结果
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return null;
    }

    public static void main(String[] args) {//测试的代码
        String url="http://172.16.172.128:8081/denglu/hello";
        String chset="UTF-8";
        HashMap map = new HashMap<>();
        map.put("name","dada1");
        String s = doGet(url, map, chset);
        System.out.println(s);

    }

}

接口提供方代码(封装的HttpClient工具类中的方法):

@Controller
@RequestMapping(value = "/denglu")
public class UserController {
    private final static transient Log logger = LogFactory.getLog(UserController.class);
    @RequestMapping(value = "/hello",method = {RequestMethod.GET})//只能get方法访问
    public @ResponseBody String home(@RequestParam Map map){
        String name = map.get("name");
        logger.info(name);
        if (!"dada".equals(name)){
            return "失败";
        }
        logger.info(map.toString());
        return "hello";
    }
}

调用结果:

被调用方的入参:

Demo2:HttpClient模拟浏览器post请求,请求接口,参数格式类似于form表单的post形式(这里HttpClient版本是4.5.5)

maven依赖:


   org.apache.httpcomponents
   httpclient
   4.5.5


   org.apache.httpcomponents
   httpmime
   4.5.5

调用方代码:

public static String doPost(String url, Map params,
                               String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {//组装参数
            List pairs= new ArrayList(
                    params.size());
            if (params != null && !params.isEmpty()) {

                for (Map.Entry entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }
            HttpEntity intoEntity = new UrlEncodedFormEntity(pairs, "utf-8");//格式化参数并设置编码
            HttpPost httpPost = new HttpPost(url);//创建HttpPost
            httpPost.setEntity(intoEntity );//把参数放到请求体里
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :"
                        + statusCode);
            }
            HttpEntity entity = response.getEntity();//获取返回参数
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return null;
    }

 public static void main(String[] args) {//测试代码
        String url="http://172.16.172.128:8081/denglu/hello";
        String chset="UTF-8";
        HashMap map = new HashMap<>();
        map.put("name","dada");
        String s = doPost(url, map, chset);
        System.out.println(s);

    }

接口提供方代码:

@Controller
@RequestMapping(value = "/denglu")
public class UserController {
    private final static transient Log logger = LogFactory.getLog(UserController.class);
    @RequestMapping(value = "/hello",method = {RequestMethod.POST})//只能post请求访问
    public @ResponseBody String home(@RequestParam Map map){
        String name = map.get("name");
        logger.info(name);
        if (!"dada".equals(name)){
            return "失败";
        }
        logger.info(map.toString());
        return "hello";
    }
}

调用结果:

被调用方的入参:

Demo3:HttpClient模拟浏览器post请求,请求接口,参数格式json格式(这里HttpClient版本是4.5.5)

maven依赖:


   org.apache.httpcomponents
   httpclient
   4.5.5


   org.apache.httpcomponents
   httpmime
   4.5.5

 

调用方代码(封装的HttpClient工具类的方法):

   public static String doPostJson(String url, String json) throws ClientProtocolException, IOException {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        // 创建http POST请求
        HttpPost httpPost = new HttpPost(url);
        if (json != null) {
            // 构造一个form表单式的实体
            StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
            // 将请求实体设置到httpPost对象中
            httpPost.setEntity(stringEntity);
        }
        CloseableHttpResponse response = null;
        try {
            // 执行请求
            response = httpClient.execute(httpPost);
            log.info("POST 访问url:" + url + " 状态为: " + response.getStatusLine().getStatusCode());
            String re = EntityUtils.toString(response.getEntity(), "UTF-8");
            log.info("返回结果为: "+re);
            return re;
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

public static void main(String[] args) throws IOException {//测试代码
        String url="http://172.16.172.128:8081/denglu/hello";
        String str="{'name':'dada'}";
        //字符串转map
        JSONObject  jsonObject = JSONObject.parseObject(str);
        Map map = (Map)jsonObject;//    //json对象转Map
        //map转字符串
        String jsonString = JSON.toJSONString(map);
        String s = doPostJson(url, jsonString);
        System.out.println(s);

    }

接口提供方代码:

 @RequestMapping(value = "/hello",method = {RequestMethod.POST})
    public @ResponseBody String home(@RequestBody JSONObject object){
        Map map = JSONObject.toJavaObject(object, Map.class);
        String name = (String) map.get("name");
        logger.info(name);
        if (!"dada".equals(name)){
            return "失败";
        }
        logger.info(map.toString());
        return "hello";
    }

参考文章地址:

https://www.imooc.com/article/70192

http://www.cnblogs.com/langtianya/p/4001499.html

总结:

上面的三个demo比较简单,但是主要让大家熟悉封装HttpClient工具类的思路,基本上按照开头的6个步骤去写代码就不会有太大的问题,根据实际开发的需求可以灵活封装HttpClient工具类的方法。我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有17位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里不明白或有不同观点的地方欢迎留言。

你可能感兴趣的:(开发问题)