Java调用Http/Https接口(3)--Commons-HttpClient调用Http/Https接口
Commons-HttpClient原来是Apache Commons项目下的一个组件,现已被HttpComponents项目下的HttpClient组件所取代;作为调用Http接口的一种选择,本文介绍下其使用方法。文中所使用到的软件版本:Java 1.8.0_191、Commons-HttpClient 3.1。
1、服务端
2、调用Http接口
2.1、GET请求
public static void get() { try { String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=" + URLEncoder.encode("李白", "utf-8"); HttpClient httpClient = new HttpClient(); GetMethod get = new GetMethod(requestPath); int status = httpClient.executeMethod(get); if (status == HttpStatus.SC_OK) { System.out.println("GET返回结果:" + new String(get.getResponseBody())); } else { System.out.println("GET返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.2、POST请求(发送键值对数据)
public static void post() { try { String requestPath = "http://localhost:8080/demo/httptest/getUser"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); String param = "userId=1000&userName=李白"; post.setRequestEntity(new ByteArrayRequestEntity(param.getBytes())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("POST返回结果:" + new String(post.getResponseBody())); } else { System.out.println("POST返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.3、POST请求(发送JSON数据)
public static void post2() { try { String requestPath = "http://localhost:8080/demo/httptest/addUser"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); post.addRequestHeader("Content-type", "application/json"); String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}"; post.setRequestEntity(new ByteArrayRequestEntity(param.getBytes())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("POST json返回结果:" + new String(post.getResponseBody())); } else { System.out.println("POST json返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.4、上传文件
public static void upload() { try { String requestPath = "http://localhost:8080/demo/httptest/upload"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); FileInputStream fileInputStream = new FileInputStream("d:/a.jpg"); post.setRequestEntity(new InputStreamRequestEntity(fileInputStream)); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("upload返回结果:" + new String(post.getResponseBody())); } else { System.out.println("upload返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.5、上传文件及发送键值对数据
public static void multi() { try { String requestPath = "http://localhost:8080/demo/httptest/multi"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); File file = new File("d:/a.jpg"); Part[] parts = {new FilePart("file", file), new StringPart("param1", "参数1", "utf-8"), new StringPart("param2", "参数2", "utf-8")}; post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("multi返回结果:" + new String(post.getResponseBody())); } else { System.out.println("multi返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.6、完整例子
package com.abc.demo.http.client; import java.io.File; import java.io.FileInputStream; import java.net.URLEncoder; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.InputStreamRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; /** * * 通过Commons-HttpClient调用Http接口 * */ public class CommonsHttpClientCase { /** * GET请求 */ public static void get() { try { String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=" + URLEncoder.encode("李白", "utf-8"); HttpClient httpClient = new HttpClient(); GetMethod get = new GetMethod(requestPath); int status = httpClient.executeMethod(get); if (status == HttpStatus.SC_OK) { System.out.println("GET返回结果:" + new String(get.getResponseBody())); } else { System.out.println("GET返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } /** * POST请求(发送键值对数据) */ public static void post() { try { String requestPath = "http://localhost:8080/demo/httptest/getUser"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); String param = "userId=1000&userName=李白"; post.setRequestEntity(new ByteArrayRequestEntity(param.getBytes())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("POST返回结果:" + new String(post.getResponseBody())); } else { System.out.println("POST返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } /** * POST请求(发送json数据) */ public static void post2() { try { String requestPath = "http://localhost:8080/demo/httptest/addUser"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); post.addRequestHeader("Content-type", "application/json"); String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}"; post.setRequestEntity(new ByteArrayRequestEntity(param.getBytes())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("POST json返回结果:" + new String(post.getResponseBody())); } else { System.out.println("POST json返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } /** * 上传文件 */ public static void upload() { try { String requestPath = "http://localhost:8080/demo/httptest/upload"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); FileInputStream fileInputStream = new FileInputStream("d:/a.jpg"); post.setRequestEntity(new InputStreamRequestEntity(fileInputStream)); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("upload返回结果:" + new String(post.getResponseBody())); } else { System.out.println("upload返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } /** * 上传文件及发送键值对数据 */ public static void multi() { try { String requestPath = "http://localhost:8080/demo/httptest/multi"; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(requestPath); File file = new File("d:/a.jpg"); Part[] parts = {new FilePart("file", file), new StringPart("param1", "参数1", "utf-8"), new StringPart("param2", "参数2", "utf-8")}; post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams())); int status = httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { System.out.println("multi返回结果:" + new String(post.getResponseBody())); } else { System.out.println("multi返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { get(); post(); post2(); upload(); multi(); } }
3、调用Https接口
与调用Http接口不一样的部分主要在设置ssl部分,设置方法是自己实现ProtocolSocketFactory接口;其ssl的设置与HttpsURLConnection很相似(参见Java调用Http/Https接口(2)--HttpURLConnection/HttpsURLConnection调用Http/Https接口);下面用GET请求来演示ssl的设置,其他调用方式类似。
package com.abc.demo.http.client; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import com.abc.demo.common.util.FileUtil; /** * * 通过Commons-HttpClient调用Https接口 * */ public class CommonsHttpClientHttpsCase { public static void main(String[] args) { try { HttpClient httpClient = new HttpClient(); /* * 请求有权威证书的地址 */ String requestPath = "https://www.baidu.com/"; GetMethod get = new GetMethod(requestPath); httpClient.executeMethod(get); System.out.println("GET1返回结果:" + new String(get.getResponseBody())); /* * 请求自定义证书的地址 */ //获取信任证书库 KeyStore trustStore = getkeyStore("jks", "d:/temp/cacerts", "123456"); //不需要客户端证书 requestPath = "https://10.49.196.10:9010/myservice"; Protocol.registerProtocol("https", new Protocol("https", new HttpsProtocolSocketFactory(trustStore), 443)); get = new GetMethod(requestPath); httpClient.executeMethod(get); System.out.println("GET2返回结果:" + new String(get.getResponseBody())); //需要客户端证书,客户端证书可以是用 keytool 生成的 pks12 格式密钥库,也可以是用 OpenSSL 生成的 pkcs12 格式证书。 requestPath = "https://10.49.196.10:9016/myservice"; KeyStore keyStore = getkeyStore("pkcs12", "d:/client.p12", "123456"); Protocol.registerProtocol("https", new Protocol("https", new HttpsProtocolSocketFactory(keyStore, "123456", trustStore), 443)); get = new GetMethod(requestPath); httpClient.executeMethod(get); System.out.println("GET3返回结果:" + new String(get.getResponseBody())); } catch (Exception e) { e.printStackTrace(); } } /** * 获取证书 * @return */ private static KeyStore getkeyStore(String type, String filePath, String password) { KeyStore keySotre = null; FileInputStream in = null; try { keySotre = KeyStore.getInstance(type); in = new FileInputStream(new File(filePath)); keySotre.load(in, password.toCharArray()); } catch (Exception e) { e.printStackTrace(); } finally { FileUtil.close(in); } return keySotre; } } final class HttpsProtocolSocketFactory implements ProtocolSocketFactory { private KeyStore keyStore; private String keyStorePassword; private KeyStore trustStore; private SSLSocketFactory sslSocketFactory = null; public HttpsProtocolSocketFactory(KeyStore keyStore, String keyStorePassword, KeyStore trustStore) { this.keyStore = keyStore; this.keyStorePassword = keyStorePassword; this.trustStore = trustStore; } public HttpsProtocolSocketFactory(KeyStore trustStore) { this.trustStore = trustStore; } private SSLSocketFactory getSSLSocketFactory() { if (sslSocketFactory != null) { return sslSocketFactory; } try { KeyManager[] keyManagers = null; TrustManager[] trustManagers = null; if (keyStore != null) { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); keyManagers = keyManagerFactory.getKeyManagers(); } if (trustStore != null) { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); trustManagerFactory.init(trustStore); trustManagers = trustManagerFactory.getTrustManagers(); } else { trustManagers = new TrustManager[] { new DefaultTrustManager() }; } SSLContext context = SSLContext.getInstance("TLSv1.2"); context.init(keyManagers, trustManagers, null); sslSocketFactory = context.getSocketFactory(); return sslSocketFactory; } catch (Exception e) { e.printStackTrace(); } return null; } @Override public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException { return getSSLSocketFactory().createSocket(host, port, localAddress, localPort); } @Override public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); if (timeout == 0) { return getSSLSocketFactory().createSocket(host, port, localAddress, localPort); } else { Socket socket = getSSLSocketFactory().createSocket(); SocketAddress localAddr = new InetSocketAddress(localAddress, localPort); SocketAddress remoteAddr = new InetSocketAddress(host, port); socket.bind(localAddr); socket.connect(remoteAddr, timeout); return socket; } } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLSocketFactory().createSocket(host, port); } } final class DefaultTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }