背景
一些用户请求在某些情况下是可能重复发送的,如果是查询类操作并无大碍,但其中有些涉及写入操作,一旦重复了,可能会导致很严重的后果。例如交易接口如果重复请求,可能会重复下单。
问题
假设我们把请求参数(JSON)按KEY做升序排序,排序后拼成一个字符串,作为 KEY 值呢?但这可能非常的长,所以我们可以考虑对这个字符串求一个 MD5 作为参数的摘要,以这个摘要去取代 reqParam 的位置。
String KEY = "dedup:U="+userId + "M=" + method + "P=" + reqParamMD5;
这样,请求的唯一标识就打上了!
上面的问题其实已经是一个很不错的解决方案了,但是实际投入使用的时候可能发现有些问题:某些请求用户短时间内重复的点击了(例如 1000 毫秒发送了三次请求),但绕过了上面的去重判断(不同的 KEY 值)。
原因是这些请求参数的字段里面,是带时间字段的,这个字段标记用户请求的时间,服务端可以借此丢弃掉一些老的请求(例如5秒前)。
解决方案
这种请求,我们也很可能需要挡住后面的重复请求。所以求业务参数摘要之前,需要剔除这类时间字段。还有类似的字段可能是 GPS 的经纬度字段
代码实现
请求去重工具类的代码
{"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"}
}
//移除某个属性,以不返回该数据
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="";//移除某个属性,以不返回该数据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移除對象中不需要的屬性或字段
JArray對應的是集合,JObject對應一條記錄
//list是一個C#List<T>對象泛型集合
JArray jArray = JArray.FromObject(list);
//方式二:這樣也行
//JArray jArray =JArray.Parse(skuListJson);
foreach (JObject item in jArray)
{ //移除屬性SysNo、ProductCategorySysNoitem.Remove("SysNo");item.Remove("ProductCategorySysNo");
}
//最後在將jArray序列化為json字符串
string skuListJson = JsonConvert.SerializeObject(jArray);