Jfinal HttpKit.post(url,data)源码解析
2017-12-02 17:24
381 查看
使用Jfinal来测试一个接口非常方便,只需要发送一个post请求即可。最近跟踪源码,终于知道底层封装是怎么走的。
首先:
使用实例:
第一个参数是请求地址,第二个参数是拼装的json串。
先调用带四个参数的post方法。
buildUrlWithQueryString方法主要是根据url和查询参数构建真实的访问url
如
以下是设置默认的CHARSET编码
成功拼接好了请求访问地址,接下来就是根据url,使用post方法,以及头部信息headers得到HttpURLConnection。
Https的SocketFactory工厂的初始化。
都是采用默认的实现
根据连接输出结果,比较简单,就是文件流的读取和写入
首先:
使用实例:
String result = HttpKit.post(url, "{'api': 'uac','action': 'getAccounts'}");
第一个参数是请求地址,第二个参数是拼装的json串。
先调用带四个参数的post方法。
public static String post(String url, String data) { return post(url, null, data, null); }
/** * Send POST request */ public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) { /**使用的是JDK自带的java.net.HttpURLConnection**/ HttpURLConnection conn = null; try { /**根据请求地址url和查询参数queryParas和请求头headers得到连接信息**/ conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), POST, headers); /**建立连接**/ conn.connect(); OutputStream out = conn.getOutputStream(); out.write(data != null ? data.getBytes(CHARSET) : null); out.flush(); out.close(); /**根据连接返回响应字符串**/ return readResponseString(conn); } catch (Exception e) { throw new RuntimeException(e); } finally { /**关闭连接,也就是说发送一次post请求,连接用完之后会直接关闭**/ if (conn != null) { conn.disconnect(); } } }
buildUrlWithQueryString方法主要是根据url和查询参数构建真实的访问url
如
http://ip:port/urlPath?username=admin&password=123456
/** * Build queryString of the url */ private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) { /**如果没有参数,直接返回url**/ if (queryParas == null || queryParas.isEmpty()) return url; StringBuilder sb = new StringBuilder(url); boolean isFirst; /**如果url地址本身没有?,就直接拼接一个?**/ if (!url.contains("?")) { isFirst = true; sb.append("?"); } else { isFirst = false; } /**遍历queryParas Map**/ for (Entry<String, String> entry : queryParas.entrySet()) { /**如果有?就直接拼接key=value,否则在原来的基础上&key=value**/ if (isFirst) isFirst = false; else sb.append("&"); String key = entry.getKey(); String value = entry.getValue(); if (StrKit.notBlank(value)) /**对value进行转码,防止特殊字符之类的,CHARSET是默认的UTF-8,可以通过发送Post之前调用下HttpKit.setCharSet(String charSet)方法**/ try {value = URLEncoder.encode(value, CHARSET);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);} sb.append(key).append("=").append(value); } return sb.toString(); }
以下是设置默认的CHARSET编码
/**成员遍历,非final修饰**/ private static String CHARSET = "UTF-8"; public static void setCharSet(String charSet) { if (StrKit.isBlank(charSet)) { throw new IllegalArgumentException("charSet can not be blank."); } HttpKit.CHARSET = charSet; }
成功拼接好了请求访问地址,接下来就是根据url,使用post方法,以及头部信息headers得到HttpURLConnection。
private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException { /**看到没,jfinal就是封装而已,没有其他,用的是JDK自带的java.net.URL**/ URL _url = new URL(url); HttpURLConnection conn = (HttpURLConnection)_url.openConnection(); /**对Https的支持**/ if (conn instanceof HttpsURLConnection) { /**sslSocketFactory的值见后面的initSSLSocketFactory**/ ((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory); ((HttpsURLConnection)conn).setHostnameVerifier(trustAnyHostnameVerifier); } conn.setRequestMethod(method); conn.setDoOutput(true); conn.setDoInput(true); /**设置了默认连接超时时间19秒**/ conn.setConnectTimeout(19000); /**设置读超时时间19秒**/ conn.setReadTimeout(19000); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"); if (headers != null && !headers.isEmpty()) for (Entry<String, String> entry : headers.entrySet()) conn.setRequestProperty(entry.getKey(), entry.getValue()); return conn; }
Https的SocketFactory工厂的初始化。
private static final SSLSocketFactory sslSocketFactory = initSSLSocketFactory(); private static final TrustAnyHostnameVerifier trustAnyHostnameVerifier = new HttpKit().new TrustAnyHostnameVerifier(); private static SSLSocketFactory initSSLSocketFactory() { try { /**内部类实现了 javax.net.ssl.X509TrustManager**/ TrustManager[] tm = {new HttpKit().new TrustAnyTrustManager() }; SSLContext sslContext = SSLContext.getInstance("TLS"); // ("TLS", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } }
都是采用默认的实现
private class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } private class TrustAnyTrustManager implements X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }
根据连接输出结果,比较简单,就是文件流的读取和写入
private static String readResponseString(HttpURLConnection conn) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; try { inputStream = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET)); String line = null; while ((line = reader.readLine()) != null){ sb.append(line).append("\n"); } return sb.toString(); } catch (Exception e) { throw new RuntimeException(e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { LogKit.error(e.getMessage(), e); } } } }
相关文章推荐
- HttpURLConnection post解析
- 复习URLHttpConnection方式GET,POST方式链接网络解析uri
- HttpURLConnection form-data的post方式,提交图片信息
- How to use HttpURLConnection POST data to web server?
- HttpURLConnection的post请求,什么时候发出,writeData存在什么地方
- XMLHttpRequestjQuery.post(url, [data], [callback], [type])
- 复习URLHttpConnection方式GET,POST方式链接网络解析uri
- How to use HttpURLConnection POST data to web server?
- http://a.codekk.com/detail/Android/grumoon/Volley 源码解析
- php7.0.25 $GLOBALS["HTTP_RAW_POST_DATA"]不可用
- Http学习之使用HttpURLConnection发送post和get请求
- httpurlconnection 和 httpclient 发送get、post请求
- java 源码 解析 URL 链接,本方法是截取淘宝商品的 ID
- Http学习之使用HttpURLConnection发送post请求深入
- Http学习之使用HttpURLConnection发送post和get请求
- HttpURLConnection 向服务器发送post和get请求 并接收响应
- C#中HttpWebRequest用Post提交Content-Type: multipart/form-data; boundary=
- Django源码解析(五) URL配置
- HttpPost 传输Json数据并解析
- jfinal源码解析