第一章 HttpClient的使用

来源:http://www.cnblogs.com/java-zhao/archive/2016/01/04/5099063.html
-Advertisement-
Play Games

1、http協議(這一塊兒有時間的話會做記錄)2、常用的兩種RPC方式基於http協議:HttpClient和JDK自己的Http操作類基於TCP或UDP協議:mina2和netty(這一部分以後有時間做記錄)3、HttpClient工具類的編寫(只列出了兩個最常用的方法get和post)使用場合:...


1、http協議(這一塊兒有時間的話會做記錄)

2、常用的兩種RPC方式

  • 基於http協議:HttpClient和JDK自己的Http操作類
  • 基於TCP或UDP協議:mina2和netty(這一部分以後有時間做記錄)

3、HttpClient工具類的編寫(只列出了兩個最常用的方法get和post)

使用場合:我們可以在網頁發送get或post請求去訪問伺服器server1,那我們在Java程式中想要模擬網頁向伺服器server1發送get和post請求的時候怎麼辦?--用HttpClient

版本:httpClient4.2.6(jar或者maven坐標自己加上)

maven坐標:

1 <dependency>
2     <groupId>org.apache.httpcomponents</groupId>
3     <artifactId>httpclient</artifactId>
4     <version>4.2.6</version>
5 </dependency>
View Code

代碼實現(兩個類):

MyX509TrustManager(自定義的信任管理器) 

 1 package com.util;
 2 
 3 import java.security.cert.CertificateException;
 4 import java.security.cert.X509Certificate;
 5 
 6 import javax.net.ssl.X509TrustManager;
 7 
 8 /**
 9  * 自定義的信任管理器
10  */
11 public class MyX509TrustManager implements X509TrustManager {
12     /**
13      * 檢查客戶端證書,若不信任,拋出異常
14      */
15     public void checkClientTrusted(X509Certificate[] arg0, String arg1)
16             throws CertificateException {
17     }
18     /**
19      * 檢查服務端證書,若不信任,拋出異常,反之,若不拋出異常,則表示信任(所以,空方法代表信任所有的服務端證書)
20      */
21     public void checkServerTrusted(X509Certificate[] arg0, String arg1)
22             throws CertificateException {
23     }
24     /**
25      * 返回受信任的X509證書數組
26      */
27     public X509Certificate[] getAcceptedIssuers() {
28         return null;
29     }
30 }
View Code

 HttpClientUtil:

  1 package com.util;
  2 
  3 import java.io.IOException;
  4 import java.security.KeyManagementException;
  5 import java.security.NoSuchAlgorithmException;
  6 import java.security.NoSuchProviderException;
  7 import java.security.SecureRandom;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 import java.util.Map;
 11 import java.util.Properties;
 12 import java.util.Set;
 13 
 14 import javax.net.ssl.SSLContext;
 15 import javax.net.ssl.TrustManager;
 16 
 17 import org.apache.commons.collections4.MapUtils;
 18 import org.apache.http.HttpEntity;
 19 import org.apache.http.HttpResponse;
 20 import org.apache.http.HttpStatus;
 21 import org.apache.http.HttpVersion;
 22 import org.apache.http.NameValuePair;
 23 import org.apache.http.StatusLine;
 24 import org.apache.http.client.ClientProtocolException;
 25 import org.apache.http.client.HttpClient;
 26 import org.apache.http.client.entity.UrlEncodedFormEntity;
 27 import org.apache.http.client.methods.HttpGet;
 28 import org.apache.http.client.methods.HttpPost;
 29 import org.apache.http.client.utils.URLEncodedUtils;
 30 import org.apache.http.conn.scheme.PlainSocketFactory;
 31 import org.apache.http.conn.scheme.Scheme;
 32 import org.apache.http.conn.scheme.SchemeRegistry;
 33 import org.apache.http.conn.ssl.SSLSocketFactory;
 34 import org.apache.http.impl.client.DefaultHttpClient;
 35 import org.apache.http.impl.conn.PoolingClientConnectionManager;
 36 import org.apache.http.message.BasicNameValuePair;
 37 import org.apache.http.params.BasicHttpParams;
 38 import org.apache.http.params.CoreConnectionPNames;
 39 import org.apache.http.params.CoreProtocolPNames;
 40 import org.apache.http.params.HttpParams;
 41 import org.apache.http.util.EntityUtils;
 42 
 43 /**
 44  * 對HTTPClient的封裝
 45  */
 46 public class HttpClientUtil {
 47 
 48     private static final String ENCODING = "UTF-8";
 49 
 50     private static HttpClient client = null;
 51     private static SchemeRegistry schemeRegistry;        //協議控制
 52     private static PoolingClientConnectionManager ccm;  //HttpClient連接池(多連接的線程安全的管理器)
 53 
 54     static {
 55         try {
 56             /*
 57              * 與https請求相關的操作
 58              */
 59             SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE");
 60             sslContext.init(null, new TrustManager[]{new MyX509TrustManager()}, new SecureRandom());
 61             SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
 62             /*
 63              * 定義訪問協議
 64              */
 65             schemeRegistry = new SchemeRegistry();
 66             schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));//http
 67             schemeRegistry.register(new Scheme("https", 443, socketFactory));//https
 68         } catch (NoSuchAlgorithmException e) {
 69             e.printStackTrace();
 70         } catch (NoSuchProviderException e) {
 71             e.printStackTrace();
 72         } catch (KeyManagementException e) {
 73             e.printStackTrace();
 74         }
 75         
 76         Properties props = FileUtil.loadProps("http.properties");//載入屬性文件
 77         
 78         // 連接池管理
 79         ccm = new PoolingClientConnectionManager(schemeRegistry);
 80         ccm.setDefaultMaxPerRoute(FileUtil.getInt(props, "httpclient.max.conn.per.route", 20));//每個路由的最大連接數
 81         ccm.setMaxTotal(FileUtil.getInt(props, "httpclient.max.conn.total", 400));//最大總連接數
 82 
 83         HttpParams httpParams = new BasicHttpParams();
 84         httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, FileUtil.getInt(props, "httpclient.max.conn.timeout", 1000));//連接超時時間(ms)
 85         httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, FileUtil.getInt(props, "httpclient.max.socket.timeout", 2000));//操作超時時間(ms)
 86         httpParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1);//設置http1.1或http1.0
 87 
 88         client = new DefaultHttpClient(ccm, httpParams);//一個客戶端就有一個連接池
 89     }
 90 
 91     /**
 92      * get請求
 93      * @param url       請求URL
 94      * @param paramMap    請求參數
 95      * @param headerMap    請求頭信息
 96      */
 97     public static String get(String url,
 98                              Map<String, String> paramMap, 
 99                              Map<String, String> headerMap) throws ClientProtocolException, 
100                                                                     IOException {
101         /*
102          * 拼接URL與參數
103          */
104         if (MapUtils.isNotEmpty(paramMap)) {
105             List<NameValuePair> params = new ArrayList<NameValuePair>();
106             for (String key : paramMap.keySet()) {
107                 params.add(new BasicNameValuePair(key, paramMap.get(key)));
108             }
109             String queryString = URLEncodedUtils.format(params,ENCODING);
110             if (url.indexOf("?") > -1) {//存在?,表示這時的URL已經帶參數了
111                 url += "&" + queryString;
112             } else {
113                 url += "?" + queryString;
114             }
115         }
116 
117         HttpGet httpGet = new HttpGet(url);
118 
119         /*
120          * 設置頭信息
121          */
122         if (MapUtils.isNotEmpty(headerMap)) {
123             Set<String> keySet = headerMap.keySet();
124             for (String key : keySet) {
125                 httpGet.addHeader(key, headerMap.get(key));
126             }
127         }
128 
129         String result = "";
130         
131         HttpResponse response = client.execute(httpGet);    //發出get請求
132         StatusLine status = response.getStatusLine();        //獲取返回的狀態碼
133         HttpEntity entity = response.getEntity();            //獲取返回的響應內容
134         if (status.getStatusCode() == HttpStatus.SC_OK) {    //200
135             result = EntityUtils.toString(entity, ENCODING);
136         } 
137         
138         httpGet.abort();//中止請求,連接被釋放回連接池
139         return result;
140     }
141 
142     /**
143      * post請求
144      * @param url        //請求URL
145      * @param paramMap    //請求參數
146      * @param headerMap    //請求頭信息
147      */
148     public static String post(String url,
149                               Map<String, String> paramMap, 
150                               Map<String, String> headerMap) throws ClientProtocolException, 
151                                                                       IOException {
152         HttpPost httpPost = new HttpPost(url);
153         /*
154          * 處理參數
155          */
156         List<NameValuePair> params = new ArrayList<NameValuePair>();
157         if (MapUtils.isNotEmpty(paramMap)) {
158             Set<String> keySet = paramMap.keySet();
159             for (String key : keySet) {
160                 params.add(new BasicNameValuePair(key, paramMap.get(key)));
161             }
162         }
163 
164         /*
165          * 設置頭信息
166          */
167         if (MapUtils.isNotEmpty(headerMap)) {
168             Set<String> keySet = headerMap.keySet();
169             for (String key : keySet) {
170                 httpPost.addHeader(key, headerMap.get(key));
171             }
172         }
173 
174         String result = "";
175         
176         httpPost.setEntity(new UrlEncodedFormEntity(params, ENCODING));//設置參數
177         HttpResponse response = client.execute(httpPost);               //發出post請求
178         StatusLine status = response.getStatusLine();                   //獲取返回的狀態碼
179         HttpEntity entity = response.getEntity();                       //獲取響應內容
180         if (status.getStatusCode() == HttpStatus.SC_OK) {
181             result = EntityUtils.toString(entity, ENCODING);
182         }
183         
184         httpPost.abort();//中止請求,連接被釋放回連接池
185         return result;
186     }
187 
188     /**
189      * 測試
190      */
191     public static void main(String[] args) {
192         try {
193             System.out.println(HttpClientUtil.get("https://www.baidu.com/", null, null));
194             //System.out.println(HttpClientUtil.post("http://www.cppblog.com/iuranus/archive/2010/07/04/119311.html", null, null));
195         } catch (ClientProtocolException e) {
196             e.printStackTrace();
197         } catch (IOException e) {
198             e.printStackTrace();
199         }
200     }
201 }
View Code

在該代碼中,還有兩個部分:一個屬性文件http.properties和一個文件操作類FileUtil。這兩部分,請查看下邊的這個鏈接:

http://www.cnblogs.com/java-zhao/p/5098813.html

註意:

  • 我們發起的請求可以使http的,也可以是https(相當於http+SSL/TLS+數字證書的組合,是一種安全協議)的,對於https相關的請求而言,我們需要編寫一些代碼,來做特殊的處理。一般而言,處理https請求有兩種方法:

  1)將https伺服器端的安全證書導入到客戶端的TrustStore文件中去,具體的原理見"《微信公眾平臺應用開發(方法、技巧與案例)》第5章"或者去查看柳峰的博客

    2)實現自定義的信任管理器(eg.MyX509TrustManager),需要實現X509TrustManager介面,並實現其中的三個方法。註意:這個類的註釋一定要看

        第一種方法需要手工導入證書,很費事;第二種方法十分靈活

  • 對於HttpClientUtil中,每一塊做什麼查看註釋,這裡:解釋httpclient.max.conn.per.route(每個路由的最大連接數):這裡路由的概念可以理解為"運行環境機器到目標機器"的一條線路。舉例來說,我們使用HttpClient的實現來分別請求 www.baidu.com 的資源和 www.bing.com 的資源那麼他就會產生兩個route(路由),根據如上設置為20,就可以為上邊兩條route分別設置最大20個併發連接數。
  • 假如只有HttpClientUtil使用MyX509TrustManager,我們也可以將MyX509TrustManager作為HttpClientUtil的一個內部類,代碼如下:
  •   1 package com.util;
      2 
      3 import java.io.IOException;
      4 import java.security.KeyManagementException;
      5 import java.security.NoSuchAlgorithmException;
      6 import java.security.NoSuchProviderException;
      7 import java.security.SecureRandom;
      8 import java.security.cert.CertificateException;
      9 import java.security.cert.X509Certificate;
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 import java.util.Map;
     13 import java.util.Properties;
     14 import java.util.Set;
     15 
     16 import javax.net.ssl.SSLContext;
     17 import javax.net.ssl.TrustManager;
     18 import javax.net.ssl.X509TrustManager;
     19 
     20 import org.apache.commons.collections4.MapUtils;
     21 import org.apache.http.HttpEntity;
     22 import org.apache.http.HttpResponse;
     23 import org.apache.http.HttpStatus;
     24 import org.apache.http.HttpVersion;
     25 import org.apache.http.NameValuePair;
     26 import org.apache.http.StatusLine;
     27 import org.apache.http.client.ClientProtocolException;
     28 import org.apache.http.client.HttpClient;
     29 import org.apache.http.client.entity.UrlEncodedFormEntity;
     30 import org.apache.http.client.methods.HttpGet;
     31 import org.apache.http.client.methods.HttpPost;
     32 import org.apache.http.client.utils.URLEncodedUtils;
     33 import org.apache.http.conn.scheme.PlainSocketFactory;
     34 import org.apache.http.conn.scheme.Scheme;
     35 import org.apache.http.conn.scheme.SchemeRegistry;
     36 import org.apache.http.conn.ssl.SSLSocketFactory;
     37 import org.apache.http.impl.client.DefaultHttpClient;
     38 import org.apache.http.impl.conn.PoolingClientConnectionManager;
     39 import org.apache.http.message.BasicNameValuePair;
     40 import org.apache.http.params.BasicHttpParams;
     41 import org.apache.http.params.CoreConnectionPNames;
     42 import org.apache.http.params.CoreProtocolPNames;
     43 import org.apache.http.params.HttpParams;
     44 import org.apache.http.util.EntityUtils;
     45 
     46 /**
     47  * 對HTTPClient的封裝
     48  */
     49 public class HttpClientUtilWithMyX509TrustMananer {
     50 
     51     private static final String ENCODING = "UTF-8";
     52 
     53     private static HttpClient client = null;
     54     private static SchemeRegistry schemeRegistry; // 協議控制
     55     private static PoolingClientConnectionManager ccm; // HttpClient連接池(多連接的線程安全的管理器)
     56 
     57     static {
     58         try {
     59             /*
     60              * 與https請求相關的操作
     61              */
     62             SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
     63             sslContext.init(null,
     64                             new TrustManager[] { getMyX509TrustManager() },
     65                             new SecureRandom());
     66             SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
     67             /*
     68              * 定義訪問協議
     69              */
     70             schemeRegistry = new SchemeRegistry();
     71             schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));// http
     72             schemeRegistry.register(new Scheme("https", 443, socketFactory));// https
     73         } catch (NoSuchAlgorithmException e) {
     74             e.printStackTrace();
     75         } catch (NoSuchProviderException e) {
     76             e.printStackTrace();
     77         } catch (KeyManagementException e) {
     78             e.printStackTrace();
     79         }
     80 
     81         Properties props = FileUtil.loadProps("http.properties");// 載入屬性文件
     82 
     83         // 連接池管理
     84         ccm = new PoolingClientConnectionManager(schemeRegistry);
     85         ccm.setDefaultMaxPerRoute(FileUtil.getInt(props,"httpclient.max.conn.per.route", 20));// 每個路由的最大連接數
     86         ccm.setMaxTotal(FileUtil.getInt(props, "httpclient.max.conn.total", 400));// 最大總連接數
     87 
     88         HttpParams httpParams = new BasicHttpParams();
     89         httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,FileUtil.getInt(props, "httpclient.max.conn.timeout", 1000));// 連接超時時間(ms)
     90         httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT,FileUtil.getInt(props, "httpclient.max.socket.timeout", 2000));// 操作超時時間(ms)
     91         httpParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1);// 設置http1.1或http1.0
     92 
     93         client = new DefaultHttpClient(ccm, httpParams);// 一個客戶端就有一個連接池
     94     }
     95 
     96     /**
     97      * get請求
     98      * @param url       請求URL
     99      * @param paramMap  請求參數
    100      * @param headerMap 請求頭信息
    101      */
    102     public static String get(String url, 
    103                              Map<String, String> paramMap,
    104                              Map<String, String> headerMap) throws ClientProtocolException,
    105                                                                     IOException {
    106         /*
    107          * 拼接URL與參數
    108          */
    109         if (MapUtils.isNotEmpty(paramMap)) {
    110             List<NameValuePair> params = new ArrayList<NameValuePair>();
    111             for (String key : paramMap.keySet()) {
    112                 params.add(new BasicNameValuePair(key, paramMap.get(key)));
    113             }
    114             String queryString = URLEncodedUtils.format(params, ENCODING);
    115             if (url.indexOf("?") > -1) {// 存在?,表示這時的URL已經帶參數了
    116                 url += "&" + queryString;
    117             } else {
    118                 url += "?" + queryString;
    119             }
    120         }
    121 
    122         HttpGet httpGet = new HttpGet(url);
    123 
    124         /*
    125          * 設置頭信息
    126          */
    127         if (MapUtils.isNotEmpty(headerMap)) {
    128             Set<String> keySet = headerMap.keySet();
    129             for (String key : keySet) {
    130                 httpGet.addHeader(key, headerMap.get(key));
    131             }
    132         }
    133 
    134         String result = "";
    135 
    136         HttpResponse response = client.execute(httpGet); // 發出get請求
    137         StatusLine status = response.getStatusLine(); // 獲取返回的狀態碼
    138         HttpEntity entity = response.getEntity(); // 獲取返回的響應內容
    139         if (status.getStatusCode() == HttpStatus.SC_OK) { // 200
    140             result = EntityUtils.toString(entity, ENCODING);
    141         }
    142 
    143         httpGet.abort();// 中止請求,連接被釋放回連接池
    144         return result;
    145     }
    146 
    147     /**
    148      * post請求
    149      * @param url       請求URL
    150      * @param paramMap  請求參數
    151      * @param headerMap 請求頭信息
    152      */
    153     public static String post(String url, 
    154                               Map<String, String> paramMap,
    155                               Map<String, String> headerMap) throws ClientProtocolException,
    156                                                                       IOException {
    157         HttpPost httpPost = new HttpPost(url);
    158         /*
    159          * 處理參數
    160          */
    161         List<NameValuePair> params = new ArrayList<NameValuePair>();
    162         if (MapUtils.isNotEmpty(paramMap)) {
    163             Set<String> keySet = paramMap.keySet();
    164             for (String key : keySet) {
    165                 params.add(new BasicNameValuePair(key, paramMap.get(key)));
    166             }
    167         }
    168 
    169         /*
    170          * 設置頭信息
    171          */
    172         if (MapUtils.isNotEmpty(headerMap)) {
    173             Set<String> keySet = headerMap.keySet();
    174             for (String key : keySet) {
    175                 httpPost.addHeader(key, headerMap.get(key));
    176             }
    177         }
    178 
    179         String result = "";
    180 
    181         httpPost.setEntity(new UrlEncodedFormEntity(params, ENCODING));// 設置參數
    182         HttpResponse response = client.execute(httpPost); // 發出post請求
    183         StatusLine status = response.getStatusLine(); // 獲取返回的狀態碼
    184         HttpEntity entity = response.getEntity(); // 獲取響應內容
    185         if (status.getStatusCode() == HttpStatus.SC_OK) {
    186             result = EntityUtils.toString(entity, ENCODING);
    187         }
    188 
    189         httpPost.abort();// 中止請求,連接被釋放回連接池
    	   
    
    
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程的一些主要狀態以及狀態之間的裝換 (如下圖)主要狀態為:1.新建 2.就緒3.運行 4阻塞 5.死亡 其中:join()可以用來邀請其他線程先執行 yield()告訴系統"把自己的CPU時間讓掉,讓其他線程或者自己運行"引入線程的好處:1 創建一個線程花費的時間少。2 兩個線...
  • python列表排序 python字典排序 sortedList的元素可以是各種東西,字元串,字典,自己定義的類等。sorted函數用法如下:sorted(data, cmp=None, key=None, reverse=False) 其中,data是待排序數據,可以使List或者iter...
  • 在開發中遇到將form中的name值一樣的多個input元素傳遞到後臺,我用的是springmvc。剛開始的時候老是報400的請求錯誤。後來查了下資料,其實解決方案挺簡單的。我的後臺controller的代碼如下: 1 @RequestMapping(value = { "/examine" }, ...
  • 早上老大扔了個設備來說要做個搖一搖紅包 就上網找了下 強大的度娘都找不到大神們分享出來的源碼 只能自己埋頭去寫寫了微信官方說明如下搖一搖紅包說明功能說明搖一搖周邊紅包介面是為線下商戶提供的發紅包功能。用戶可以在商家門店等線下場所通過搖一搖周邊領取商家發放的紅包,線上上轉發分享無效。開發者可通過介面開...
  • 我們首先來看看官方的文檔怎麼說:如果用戶在微信客戶端中訪問第三方網頁,公眾號可以通過微信網頁授權機制,來獲取用戶基本信息,進而實現業務邏輯。關於網頁授權回調功能變數名稱的說明1、在微信公眾號請求用戶網頁授權之前,開發者需要先到公眾平臺官網中的開發者中心頁配置授權回調功能變數名稱。請註意,這裡填寫的是功能變數名稱(是一個字元...
  • 1.在使用ExtJS在Server端進行網頁開發時,常常會出現關鍵字對應錯誤的問題。例如app\store\xxx\XXX.js中的totalProperty:'XXX',XXX對應的是Action中resultMap.put("aaa",bbb)的aaa。這個是固定的頁面統計條數的方法。root:...
  • 代碼中常有類似的如下的輸入迴圈 char c; while((c=getchar())!=EOF).... 如果輸入 字元+換行時,迴圈的代碼會執行兩次,主要是換行鍵作為字元存到了緩存隊列中,第一次c為輸入的值,第二次c為換行符 ,可以通過fflush(stdin);清除 ...
  • fdisk 分區fdisk /dev/sdb-p查看當前分區-t 改分區號-w將分區表寫進磁碟-n創建分區 -p主分區 -e拓展分區partprobe 讓內核更新分區信息cat /proc/partitions 查看磁碟分區創建文件系統(格式化文件系統)mke2fs -t ext4 /...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...