巧用Newtonsoft.Json處理重復(fù)請(qǐng)求/并發(fā)請(qǐng)求?
背景
一些用戶(hù)請(qǐng)求在某些情況下是可能重復(fù)發(fā)送的,如果是查詢(xún)類(lèi)操作并無(wú)大礙,但其中有些涉及寫(xiě)入操作,一旦重復(fù)了,可能會(huì)導(dǎo)致很?chē)?yán)重的后果。例如交易接口如果重復(fù)請(qǐng)求,可能會(huì)重復(fù)下單。
問(wèn)題
假設(shè)我們把請(qǐng)求參數(shù)(JSON)按KEY做升序排序,排序后拼成一個(gè)字符串,作為 KEY 值呢?但這可能非常的長(zhǎng),所以我們可以考慮對(duì)這個(gè)字符串求一個(gè) MD5 作為參數(shù)的摘要,以這個(gè)摘要去取代 reqParam 的位置。
String KEY = "dedup:U="+userId + "M=" + method + "P=" + reqParamMD5;這樣,請(qǐng)求的唯一標(biāo)識(shí)就打上了!
上面的問(wèn)題其實(shí)已經(jīng)是一個(gè)很不錯(cuò)的解決方案了,但是實(shí)際投入使用的時(shí)候可能發(fā)現(xiàn)有些問(wèn)題:某些請(qǐng)求用戶(hù)短時(shí)間內(nèi)重復(fù)的點(diǎn)擊了(例如 1000 毫秒發(fā)送了三次請(qǐng)求),但繞過(guò)了上面的去重判斷(不同的 KEY 值)。
原因是這些請(qǐng)求參數(shù)的字段里面,是帶時(shí)間字段的,這個(gè)字段標(biāo)記用戶(hù)請(qǐng)求的時(shí)間,服務(wù)端可以借此丟棄掉一些老的請(qǐng)求(例如5秒前)。
解決方案
這種請(qǐng)求,我們也很可能需要擋住后面的重復(fù)請(qǐng)求。所以求業(yè)務(wù)參數(shù)摘要之前,需要剔除這類(lèi)時(shí)間字段。還有類(lèi)似的字段可能是 GPS 的經(jīng)緯度字段
代碼實(shí)現(xiàn)
請(qǐng)求去重工具類(lèi)的代碼
{
"Result": {
"AccName": "New 2018-05-08 11:22:44",
"BeginTime": "1970-01-01T00:00:00",
"EndTime": null,
"MaxDrawDownRate": 0.0,
"AccountCorporation": "",
"YearProfitPrecentage": 0.0,
"CreateUserName": "MatrixUser",
"HasDataType": "期貨,股票",
"DataTypes": [
{
"Value": "8",
"Text": "期貨",
"Name": null
},
{
"Value": "1",
"Text": "股票",
"Name": null
}
],
"SumAmount": 2000000.0,
"CapitaleAmount": 2000000.0,
"Cash": 0.0
},
"Head": {
"Message": "獲取成功",
"Code": "200",
"CallTime": "2018-05-24 15:19:04"
}
}//移除某個(gè)屬性,以不返回該數(shù)據(jù)
JObject jobject = JObject.Parse(json);
JObject tokenselect = jobject.SelectToken("Result") as JObject;
tokenselect.Remove("DataTypes");using Newtonsoft.Json.Linq;
public ActionResult Detail(int id)
//待處理的josn字符串
string json="";
//移除某個(gè)屬性,以不返回該數(shù)據(jù)
JObject jobject = JObject.Parse(json);
JObject tokenselect = jobject.SelectToken("Result") as JObject;
tokenselect.Remove("DataTypes");
return Json(tokenselect);
}
var skuListJson=[{"ProductCategorySysNo":"467011276116070400","MalfunctionsSysNo":"467011100731248640","PropertyValueSysNos":"467011331313111040,467011331510243328,467011332495904768","SysNo":"467011332256829440","Price":2500.00},{"ProductCategorySysNo":"467011276116070400","MalfunctionsSysNo":"467011100731248640","PropertyValueSysNos":"467011331313111040,467011331510243328,467011331845787648","SysNo":"467011331208253440","Price":2000.00},{"ProductCategorySysNo":"467011276116070400","MalfunctionsSysNo":"467011095232516096","PropertyValueSysNos":"467011326095396864,467011326493855744,467011330340032512","SysNo":"467011330189037568","Price":0.00}];
Newtonsoft.Json.Linq移除對(duì)象中不需要的屬性或字段
JArray對(duì)應(yīng)的是集合,JObject對(duì)應(yīng)一條記錄
//list是一個(gè)C#List<T>對(duì)象泛型集合
JArray jArray = JArray.FromObject(list);
//方式二:這樣也行
//JArray jArray =JArray.Parse(skuListJson);
foreach (JObject item in jArray)
{
//移除屬性SysNo、ProductCategorySysNo
item.Remove("SysNo");
item.Remove("ProductCategorySysNo");
}
//最後在將jArray序列化為json字符串
string skuListJson = JsonConvert.SerializeObject(jArray);




























