Apache HttpClient 实现 Java 调用 Http 接口

本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。


1 新建一个测试用 Http URL,对登录的用户名和密码进行验证,并返回验证结果

1.1 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://java.sun.com/xml/ns/javaee" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
  id="WebApp_ID" 
  version="3.0">

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>loginService</servlet-name>
    <servlet-class>service.LoginService</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>loginService</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>

</web-app>

1.2 Servlet

package service;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginService extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        OutputStream outputStream = response.getOutputStream();
        response.setHeader("content-type", "application/json;charset=UTF-8");
        String result = null;
        if (username == null) {
            result = "请输入用户名!";
        } else if (password == null) {
            result = "请输入密码!";
        } else if (!username.equals("unique")) {
            result = "用户名错误!";
        } else if (!password.equals("ASDF")) {
            result = "密码错误!";
        } else {
            result = "验证通过~~";
        }
        outputStream.write(result.getBytes("UTF-8"));
    }

}

1.3 在浏览器中测试一下:
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

2 通过 Java 代码调用

2.1 添加 Apache HttpClient 依赖包
本文使用 Maven 管理依赖,关于 Maven 的使用可以参看:Apache Maven 或上网搜索相关资料
注意:本文使用的 Apache HttpClient 版本是 4.5.3

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>jyl</groupId>
  <artifactId>Service</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.3</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>
</project>

2.2 编写单元测试

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

public class TestHttpClient {

    @Test
    public void test() {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://localhost:8080/Service/login");
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpGet);
            System.out.print("Protocol Version :: ");
            System.out.println(httpResponse.getProtocolVersion());
            System.out.println("--------------------------------------------------");
            System.out.print("Status Code :: ");
            System.out.println(httpResponse.getStatusLine().getStatusCode());
            System.out.println("--------------------------------------------------");
            System.out.print("Reason Phrase :: ");
            System.out.println(httpResponse.getStatusLine().getReasonPhrase());
            System.out.println("--------------------------------------------------");
            System.out.print("Status Line :: ");
            System.out.println(httpResponse.getStatusLine().toString());
            System.out.println("--------------------------------------------------");
            HttpEntity httpEntity = httpResponse.getEntity();
            System.out.print("Content Length :: ");
            System.out.println(httpEntity.getContentLength());
            System.out.println("--------------------------------------------------");
            System.out.print("Content Type :: ");
            System.out.println(httpEntity.getContentType());
            System.out.println("--------------------------------------------------");
            System.out.print("Content :: ");
            System.out.println(httpEntity.getContent());
            System.out.println("--------------------------------------------------");
            System.out.print("Content Text :: ");
            System.out.println(EntityUtils.toString(httpEntity));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

2.3 测试结果
这里写图片描述

2.4 修改 HttpGet 参数测试返回的 Content Text

HttpGet httpGet = new HttpGet("http://localhost:8080/Service/login?username=unique");

这里写图片描述

HttpGet httpGet = new HttpGet("http://localhost:8080/Service/login?username=unique&password=ASDF");

这里写图片描述

3 关于 org.apache.http.util.EntityUtils 的使用注意事项

官方文档中建议严格控制使用 EntityUtils 读取 HttpEntity 的信息,除非请求的 HTTP 服务器是一个授信的服务器且返回的结果长度在一定范围内,下面是官方文档中的原文

However, the use of EntityUtils is strongly discouraged unless the response entities originate from a trusted HTTP server and are known to be of limited length.

4 向 HttpGet 传递 URI 参数

可以向 HttpGet 传递一个 java.net.URI 参数代替字符串参数

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

public class TestHttpClient {

    @Test
    public void test() {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = null;
        CloseableHttpResponse httpResponse = null;
        try {
            URI uri = new URIBuilder()
                .setScheme("http")
                .setHost("localhost")
                .setPort(8080)
                .setPath("/Service/login")
                .setParameter("username", "unique")
                .setParameter("password", "ASDF")
                .build();
            httpGet = new HttpGet(uri);
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            System.out.println(EntityUtils.toString(httpEntity));
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

5 调用 Http Post 方法

5.1 将 Servlet 的 doGet 方法修改为 doPost,逻辑不变

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    OutputStream outputStream = response.getOutputStream();
    response.setHeader("content-type", "application/json;charset=UTF-8");
    String result = null;
    if (username == null) {
        result = "请输入用户名!";
    } else if (password == null) {
        result = "请输入密码!";
    } else if (!username.equals("unique")) {
        result = "用户名错误!";
    } else if (!password.equals("ASDF")) {
        result = "密码错误!";
    } else {
        result = "验证通过~~";
    }
    outputStream.write(result.getBytes("UTF-8"));
}

5.2 使用 org.apache.http.client.methods.HttpPost 替换 HttpGet

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

public class TestHttpClient {

    @Test
    public void test() {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("username", "unique"));
        params.add(new BasicNameValuePair("password", "ASDF"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, Consts.UTF_8);
        HttpPost httpPost = new HttpPost("http://localhost:8080/Service/login");
        httpPost.setEntity(entity);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            System.out.println(EntityUtils.toString(httpEntity));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

5.3 同样给以给 HttpPost 传递 java.net.URI 参数取代字符串参数

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
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.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

public class TestHttpClient {

    @Test
    public void test() {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("username", "unique"));
        params.add(new BasicNameValuePair("password", "ASDF"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, Consts.UTF_8);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        try {
            URI uri = new URIBuilder()
                .setScheme("http")
                .setHost("localhost")
                .setPort(8080)
                .setPath("/Service/login")
                .build();
            HttpPost httpPost = new HttpPost(uri);
            httpPost.setEntity(entity);
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            System.out.println(EntityUtils.toString(httpEntity));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

6 提取调用接口的工具类

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClientTool {

    public class Method {
        public static final String GET = "get";
        public static final String POST = "post";
    }

    public static String invokeHttp(String method, String uri, Map<String, String> params) 
        throws IOException {
        if (method.equals(HttpClientTool.Method.GET)) {
            if (params == null) {
                return invokeHttpGet(uri);
            } else {
                return invokeHttpGet(uri, params);
            }
        } else if (method.equals(HttpClientTool.Method.POST)) {
            return invokeHttpPost(uri, params);
        }
        return null;
    }

    public static String invokeHttp(String method, URI uri, Map<String, String> params) 
        throws IOException, URISyntaxException {
        if (method.equals(HttpClientTool.Method.GET)) {
            if (params == null) {
                return invokeHttpGet(uri);
            } else {
                return invokeHttpGet(uri, params);
            }
        } else if (method.equals(HttpClientTool.Method.POST)) {
            return invokeHttpPost(uri, params);
        }
        return null;
    }

    public static String invokeHttp(String method, String scheme, String host, int port, String path, Map<String, String> params) 
        throws ClientProtocolException, URISyntaxException, IOException {
        if (method.equals(HttpClientTool.Method.GET)) {
            return invokeHttpGet(scheme, host, port, path, params);
        } else if (method.equals(HttpClientTool.Method.POST)) {
            return invokeHttpPost(scheme, host, port, path, params);
        }
        return null;
    }

    public static final String invokeHttpGet(String uri) 
        throws ClientProtocolException, IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpGet httpGet = new HttpGet(uri);
        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpGet(String uri, Map<String, String> params) 
        throws ClientProtocolException, IOException {
        String executeUri = uri + "?";
        for (Map.Entry<String, String> entry : params.entrySet()) {
            executeUri += entry.getKey() + "=" + entry.getValue() + "&";
        }
        executeUri = executeUri.substring(0, executeUri.length() - 1);
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpGet httpGet = new HttpGet(executeUri);
        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpGet(URI uri) 
        throws ClientProtocolException, IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpGet httpGet = new HttpGet(uri);
        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpGet(URI uri, Map<String, String> params) 
        throws URISyntaxException, ClientProtocolException, IOException {
        URIBuilder builder = new URIBuilder()
            .setScheme(uri.getScheme())
            .setHost(uri.getHost())
            .setPort(uri.getPort())
            .setPath(uri.getPath());
        for (Map.Entry<String, String> entry : params.entrySet()) {
            builder.setParameter(entry.getKey(), entry.getValue());
        }
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpGet httpGet = new HttpGet(builder.build());
        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpGet(String scheme, String host, int port, String path, Map<String, String> params) 
        throws URISyntaxException, ClientProtocolException, IOException {
        URIBuilder builder = new URIBuilder()
            .setScheme(scheme)
            .setHost(host)
            .setPort(port)
            .setPath(path);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            builder.setParameter(entry.getKey(), entry.getValue());
        }
        URI uri = builder.build();
        return invokeHttpGet(uri);
    }

    public static final String invokeHttpPost(String uri, Map<String, String> params) 
        throws ClientProtocolException, IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(generatePostEntity(params));
        try {
            response = client.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            return EntityUtils.toString(httpEntity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpPost(URI uri, Map<String, String> params) 
        throws ClientProtocolException, IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(generatePostEntity(params));
        try {
            response = client.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            return EntityUtils.toString(httpEntity);
        } finally {
            release(client, response);
        }
    }

    public static final String invokeHttpPost(String scheme, String host, int port, String path, Map<String, String> params) 
        throws URISyntaxException, ClientProtocolException, IOException {
        URIBuilder builder = new URIBuilder()
            .setScheme(scheme)
            .setHost(host)
            .setPort(port)
            .setPath(path);
        URI uri = builder.build();
        return invokeHttpPost(uri, params);
    }

    private static UrlEncodedFormEntity generatePostEntity(Map<String, String> params) {
        List<NameValuePair> pairs = new ArrayList<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return new UrlEncodedFormEntity(pairs, Consts.UTF_8);
    }

    private static void release(CloseableHttpClient client, CloseableHttpResponse response) 
        throws IOException {
        if (client != null) {
            client.close();
        }
        if (response != null) {
            response.close();
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又言又语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值