2018-06-15: Java WebClient - HttpClient - 根據WebAPI請求資料

lynn_發表於2018-06-15
自定義一個 http 請求類,常用於 java 後臺程式碼根據URL地址 獲取資料

------------------------------ BEGIN ----------------------------------

1、向 WebAPI 的url 提交資料 - POST 方式

a、具體方法:

/**
 * @Title : httpPostJson
 * @Function: HTTPPost傳送JSON
 * @param url
 * @param jsonStr
 * @throws IOException
 * @throws ClientProtocolException
 */
public static String httpPostJson(String url, String jsonStr) throws ClientProtocolException, IOException {
	String resultStr = null;
	
	// 建立一個DefaultHttpClient的例項
	HttpClient httpClient = new DefaultHttpClient();
	// 建立一個HttpPost物件,傳入目標的網路地址
	HttpPost httpPost = new HttpPost(url);
	//httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
	//這裡要這樣設定...C#的介面需要
	httpPost.setHeader("contentType", "application/json;charset=UTF-8");

	// 提交的資料 - 註明utf8編碼
	StringEntity se = new StringEntity(jsonStr, "UTF-8");
	se.setContentType("text/json");
	//se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
	//這裡要這樣設定...C#的介面需要
	se.setContentEncoding(new BasicHeader("contentType", "application/json"));
	// 傳入引數
	httpPost.setEntity(se);
	
	// 呼叫HttpClient的execute()方法,並將HttpPost物件傳入;
	// 執行execute()方法之後會返回一個HttpResponse物件,伺服器所返回的所有資訊就保護在HttpResponse裡面
	HttpResponse response = httpClient.execute(httpPost);

	// 輸出呼叫結果 - 
	if(null != response && null != response.getStatusLine()){
		//先取出伺服器返回的狀態碼,如果等於200就說明請求和響應都成功了
		if(response.getStatusLine().getStatusCode() == 200){
			// 呼叫getEntity()方法獲取到一個HttpEntity例項
			// EntityUtils.toString()這個靜態方法將HttpEntity轉換成字串,防止伺服器返回的資料帶有中文,所以在轉換的時候將字符集指定成utf-8
			resultStr = EntityUtils.toString(response.getEntity(), "UTF-8");
		}else{
			System.out.println("HttpResponse StatusCode:" + response.getStatusLine().getStatusCode());
		}
	}

	return resultStr;
}
複製程式碼

b、測試方法:

String result = httpPostJson(url, paramsStr);


2、這是一個比較複雜的類、常用語GET資料,POST也行 WebClient

package com.aaa.bbb.ccc.ddd;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.routing.HttpRoutePlanner;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

public class WebClient {
	private DefaultHttpClient httpClient = new DefaultHttpClient();
	private String url;
	private HTTPMethod method;
	private byte[] content;
	private Map<String, String> headers = new HashMap<String, String>();
	private int responseCode;
	private List<NameValuePair> postParameter = new ArrayList<NameValuePair>();

	private static final Pattern pageEncodingReg = Pattern.compile("content-type.*charset=([^\">\\\\]+)",Pattern.CASE_INSENSITIVE);
	private static final Pattern headerEncodingReg = Pattern.compile("charset=(.+)", Pattern.CASE_INSENSITIVE);

	public static void main(String[] args) throws Exception {
		WebClient web = new WebClient("http://localhost:8081/test/api?s=1",HTTPMethod.GET);
		// web.enableProxy("10.10.10.10", 8080, false, null, null,"127.0.0.1");
		System.out.println(web.getTextContent());
		System.out.println("------------------------------------------");
		
		/**
		 * web.setUrl("https://mail.google.com/mail/"); 
		 * System.out.println(web.getTextContent());
		 * System.out.println("------------------------------------------");
		 * web.setUrl("http://www.snee.com/xml/crud/posttest.cgi");
		 * web.setMethod(HTTPMethod.POST);
		 * web.addPostParameter("fname", "ababab");
		 * web.addPostParameter("lname", "cdcdcd");
		 * System.out.println(web.getTextContent());
		 * System.out.println("------------------------------------------");
		 */
	}

	public WebClient(String url, HTTPMethod method) {
		this(url, method, false, null, 0, false, null, null, null);
	}

	public WebClient(String url, HTTPMethod method, String proxyHost, int proxyPort) {
	    this(url, method, true, proxyHost, proxyPort, false, null, null, null);
	}

	public WebClient(String url, HTTPMethod method, boolean useProxy, String proxyHost, int proxyPort, boolean needAuth, String username, String password, String nonProxyReg) {
	    setUrl(url);
	    setMethod(method);
	    if (useProxy) {
	    	enableProxy(proxyHost, proxyPort, needAuth, username, password,nonProxyReg);
            }
	}

	public void setMethod(HTTPMethod method) {
		this.method = method;
	}

	public void setUrl(String url) {
		if (isStringEmpty(url)) {
			throw new RuntimeException("Url不能為空.");
		}
		this.url = url;
		headers.clear();
		responseCode = 0;
		postParameter.clear();
		content = null;
		if (url.startsWith("https://")) {
			enableSSL();
		} else {
			disableSSL();
		}
	}

	public Map<String, String> getRequestHeaders() {
		return headers;
	}

	public void setHeaders(Map<String, String> headers) {
		this.headers = headers;
	}

	public void addPostParameter(String name, String value) {
		this.postParameter.add(new BasicNameValuePair(name, value));
	}

	public void setTimeout(int connectTimeout, int readTimeout) {
		HttpParams params = httpClient.getParams();
		HttpConnectionParams.setConnectionTimeout(params, connectTimeout);
		HttpConnectionParams.setSoTimeout(params, readTimeout);
	}

	private void enableSSL() {
		try {
			SSLContext sslcontext = SSLContext.getInstance("TLS");
			sslcontext.init(null, new TrustManager[] {truseAllManager}, null);
			SSLSocketFactory sf = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			// sf.setHostnameVerifier();
			Scheme https = new Scheme("https", 443, sf);
			httpClient.getConnectionManager().getSchemeRegistry().register(https);
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}

	private void disableSSL() {
		SchemeRegistry reg = httpClient.getConnectionManager().getSchemeRegistry();
		if (reg.get("https") != null) {
			reg.unregister("https");
		}
	}

	public void disableProxy() {
		httpClient.getCredentialsProvider().clear();
		httpClient.setRoutePlanner(null);
	}

	public void enableProxy(final String proxyHost, final int proxyPort, boolean needAuth, String username, String password, final String nonProxyHostRegularExpression) {
		if (needAuth) { httpClient.getCredentialsProvider()
				.setCredentials(new AuthScope(proxyHost, proxyPort), new UsernamePasswordCredentials(username, password));
		}
		// httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,new
		// HttpHost(proxyHost, proxyPort));
		httpClient.setRoutePlanner(new HttpRoutePlanner() {
			@Override
			public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext contenxt) throws HttpException {
				HttpRoute proxyRoute = new HttpRoute(target, null, new HttpHost(proxyHost, proxyPort), "https".equalsIgnoreCase(target.getSchemeName()));
				if (nonProxyHostRegularExpression == null) {
					return proxyRoute;
				}
				Pattern pattern = Pattern.compile(nonProxyHostRegularExpression, Pattern.CASE_INSENSITIVE);
				Matcher m = pattern.matcher(target.getHostName());
				if (m.find()) {
					return new HttpRoute(target, null, target, "https".equalsIgnoreCase(target.getSchemeName()));
				} else {
					return proxyRoute;
				}
			}
		});
	}

	private void fetch() throws IOException {
		if (url == null || method == null) {
			throw new RuntimeException("引數錯誤....");
		}
		httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		HttpResponse response = null;
		HttpUriRequest req = null;
		if (method.equals(HTTPMethod.GET)) {
			req = new HttpGet(url);
		} else {
			req = new HttpPost(url);
			((HttpPost) req).setEntity(new UrlEncodedFormEntity(this.postParameter, HTTP.UTF_8));
		}
		for (Entry<String, String> e : headers.entrySet()) {
			req.addHeader(e.getKey(), e.getValue());
		}
		req.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
		response = httpClient.execute(req);
		Header[] header = response.getAllHeaders();
		headers.clear();
		for (Header h : header) {
			headers.put(h.getName(), h.getValue());
		}
		content = EntityUtils.toByteArray(response.getEntity());
		responseCode = response.getStatusLine().getStatusCode();
	}

	private boolean isStringEmpty(String s) {
		return s == null || s.length() == 0;
	}

	public int getResponseCode() throws IOException {
		if (responseCode == 0) {
			fetch();
		}
		return responseCode;
	}

	public Map<String, String> getResponseHeaders() throws IOException {
		if (responseCode == 0) {
			fetch();
		}
		return headers;
	}

	public byte[] getByteArrayContent() throws IOException {
		if (content == null) {
			fetch();
		}
		return content;
	}

	public String getTextContent() throws IOException {
		if (content == null) {
			fetch();
		}
		if (content == null) {
			throw new RuntimeException("抓取類容錯誤.");
		}
		String headerContentType = null;
		if ((headerContentType = headers.get("Content-Type")) != null) {
			// use http header encoding
			Matcher m1 = headerEncodingReg.matcher(headerContentType);
			if (m1.find()) {
				return new String(content, m1.group(1));
			}
		}
		String html = new String(content);
		Matcher m2 = pageEncodingReg.matcher(html);
		if (m2.find()) {
			html = new String(content, m2.group(1));
		}
		return html;
	}

	public DefaultHttpClient getHttpClient() {
		return httpClient;
	}

	public enum HTTPMethod {
		GET, POST
	}

	private static TrustManager truseAllManager = new X509TrustManager() {
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
	};
}
複製程式碼

相關文章