Java实现客户端上传临时数据到服务器
有时为了快速响应用户的操作,可以选择现将服务器端的数据暂时保存到本地的sqlite中。后面再上传到服务器,服务器存到数据库,返回有真实ID的数据给客户端。客户端删除sqlite的临时数据,插入带有真实ID的数据。本文将介绍:“在sqlite数据库存入临时数据”、“查询临时数据”、“将查询到的临时数据上传到服务器”、“服务器端解析客户端的数据,并存到数据库中。服务器端将创建好的临时数据,返回给客户端”、“客户端收到服务器返回的数据,解析数据”、“将临时数据删除,然后插入服务器返回的数据,保持了与服务器数据的一致”。
1、在sqlite数据库存入临时数据。
设置syncDatetime字段为"1970-01-01 08:00:00 000",所有在客户端的临时数据的syncDatetime都为这个时间,查询临时数据时,就可以根据这个时间查询出数据表的临时数据:
RetailTrade retailTrade = (RetailTrade) bm;
retailTrade.setSyncDatetime(Constants.getDefaultSyncDatetime2());
retailTrade.setSyncType(BasePresenter.SYNC_Type_C);
retailTrade.setDatetimeStart(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference));
retailTrade.setDatetimeEnd(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference));
retailTrade.setSaleDatetime(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference));
long id = dao.getRetailTradeDao().insert(retailTrade);
retailTrade.setID(id);
2、查询临时数据。
查询条件为F_SyncDatetime = 0,即可查询F_SyncDatetime的时间为"1970-01-01 08:00:00 000"的数据:
BaseModel bm = new BaseModel();
bm.setSql("where F_SyncDatetime = ? and F_SlaveCreated = ?");
bm.setConditions(new String[]{"0",String.valueOf(BaseModel.EnumBoolean.EB_Yes.getIndex())});
result = dao.getRetailTradeDao().queryRaw(bm.getSql(), bm.getConditions());
3、将查询到的临时数据上传到服务器。
if (getListMasterTable().size() > 0) {
if (!httpBO.createNAsync(BaseHttpBO.INVALID_CASE_ID, listRetailTrade)) {
if (httpBO.getHttpEvent().getLastErrorCode() != ErrorInfo.EnumErrorCode.EC_NoError){
lastErrorCode = httpBO.getHttpEvent().getLastErrorCode();
}
status = EnumEventStatus.EES_SQLite_Done;
break;
}
}
RetailTrade retailTrade = new RetailTrade();
String str = retailTrade.removeJSONArrayofAttribute(gson.toJson(list));
RequestBody body = new FormBody.Builder()
.add(RetailTrade.JSON_OBJECTLIST_KEY, str)
.build();
Request req = new Request.Builder()
.url(Configuration.HTTP_IP + RetailTrade.HTTP_REQ_URL_CreateN)
.addHeader(BaseHttpBO.COOKIE, GlobalController.getInstance().getSessionID())
.post(body)
.build();
HttpRequestUnit hru = new CreateNRetailTrade();
hru.setRequest(req);
hru.setTimeout(TIME_OUT);
hru.setbPostEventToUI(true);
httpEvent.setEventProcessed(false);
httpEvent.setStatus(BaseEvent.EnumEventStatus.EES_Http_ToDo);
hru.setEvent(httpEvent);
HttpRequestManager.getCache(HttpRequestManager.EnumDomainType.EDT_Communication).pushHttpRequest(hru);
log.info("正在向服务器请求创建零售单...");
4、服务器端解析客户端的数据,并存到数据库中。服务器端将创建好的临时数据,返回给客户端。
@SuppressWarnings("unchecked")
@RequestMapping(value = "/createNEx", produces = "plain/text; charset=UTF-8", method = RequestMethod.POST)
@ResponseBody
public String createNEx(@ModelAttribute("SpringWeb") RetailTrade retailTrade, ModelMap model, HttpServletRequest req) throws Exception {
if (!canCallCurrentAction(req.getSession(), BaseAction.EnumUserScope.STAFF.getIndex())) {
logger.debug("无权访问本Action");
return null;
}
logger.info("创建多个零售单");
Company company = getCompanyFromSession(req.getSession());
String str = GetStringFromRequest(req, KEY_ObjectList, String.valueOf(BaseAction.INVALID_ID));
if (str == null || str.equals(String.valueOf(BaseAction.INVALID_ID))) {
logger.error("->数据格式不正确!");
return null;
}
Map<String, Object> params = getDefaultParamToReturn(true);
List<RetailTrade> retailTradeList = new ArrayList<RetailTrade>();
Boolean hasDBError = false;
TypeUtils.compatibleWithJavaBean = true; // 解析时将key值的解析的开头首字母的解析保留大写
JSONArray aliJsonArray = JSON.parseArray(str);
for (int i = 0; i < aliJsonArray.size(); i++) {
retailTrade = (RetailTrade) new RetailTrade().parse1(aliJsonArray.getJSONObject(i).toString());
if (retailTrade == null || retailTrade.getListSlave1() == null) {
logger.error("->零售单或零售单商品为空!");
return null;
}
String err = checkCreate(retailTrade, req, company.getDbName());
if (!"".equals(err)) {
logger.error(err + "\tretailTrade=" + retailTrade);
return null;
}
//
try {
params = handleCreateEx(retailTrade, (List<RetailTradeCommodity>) retailTrade.getListSlave1(),
(retailTrade.getListSlave2() == null || retailTrade.getListSlave2().size() == 0 ? null : (RetailTradePromoting) retailTrade.getListSlave2().get(0)),
(retailTrade.getListSlave3() == null || retailTrade.getListSlave3().size() == 0 ? null : (RetailTradeCoupon) retailTrade.getListSlave3().get(0)), company.getDbName(), req);
RetailTrade rt = (RetailTrade) params.get(KEY_Object);
if (rt != null) {
if (rt.getErrorInfo() == null) {
ErrorInfo ei = new ErrorInfo();
ei.setErrorCode(EnumErrorCode.EC_NoError);
ei.setErrorMessage("");
rt.setErrorInfo(ei);
}
if (rt.getErrorInfo().getErrorCode() != EnumErrorCode.EC_NoError) {
hasDBError = true;
}
retailTradeList.add(rt);
} else {
if (!params.get(BaseAction.JSON_ERROR_KEY).equals(EnumErrorCode.EC_NoError.toString())) {
hasDBError = true;
}
}
} catch (Exception e) {
params.put(KEY_HTMLTable_Parameter_msg, "仅上传了一部分零售单!"); // ...
}
}
if (hasDBError) { // 如果查单后发现有问题,设为部分成功,让成功的单可以在pos插入替换
params.put(JSON_ERROR_KEY, EnumErrorCode.EC_PartSuccess.toString()); // 有2种 含义,一种 是创建失败有返回用来创建的对象,一种是创建失败但是没有用来创建的对象
}
params.put(KEY_ObjectList, retailTradeList);
logger.info("返回的数据=" + JSON.toJSONStringWithDateFormat(params, DATETIME_FORMAT_Default1, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue));
return JSON.toJSONStringWithDateFormat(params, DATETIME_FORMAT_Default1, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue);
}
5、客户端收到服务器返回的数据,解析数据。
private void handleCreateN(JSONObject jsonObject) {
try {
//
JSONArray joRetailTrades = jsonObject.getJSONArray(BaseModel.JSON_OBJECTLIST_KEY);
if (joRetailTrades != null) {
RetailTrade rt = new RetailTrade();
List<BaseModel> retailTradeList = (List<BaseModel>) rt.parseN(joRetailTrades);
if (retailTradeList == null) {
log.info("CREATEN:Failed to parse RetailTrade!");
setLastErrorCode(ErrorInfo.EnumErrorCode.EC_OtherError);
} else {
log.info("ERT_RetailTrade_CreateN得到的对象是:" + retailTradeList.toString());
setListMasterTable(retailTradeList);
if (sqliteBO != null) {
sqliteBO.onResultCreateN(retailTradeList);
}
}
}
setLastErrorCode(ErrorInfo.EnumErrorCode.EC_NoError);
} catch (JSONException e) {
e.printStackTrace();
setLastErrorCode(ErrorInfo.EnumErrorCode.EC_OtherError);
log.info("同步零售单失败,失败原因:" + e.getMessage());
}
}
6、将临时数据删除,然后插入服务器返回的数据,保持了与服务器数据的一致。
log.info("已经得到服务器返回的主表和从表数据,准备删除本地的旧数据,并插入服务器的数据...");//...
log.info("旧的零售单为:" + bmOldList);
log.info("服务器返回的零售单为:" + bmNewList);
try {
if (bmNewList != null) {
for (int i = 0; i < bmNewList.size(); i++) {
RetailTrade retailTradeNew = (RetailTrade) bmNewList.get(i);
if (bmOldList != null) {
for (int j = 0; j < bmOldList.size(); j++) {
RetailTrade retailTradeOld = (RetailTrade) bmOldList.get(j);
if (retailTradeNew.getLocalSN() == retailTradeOld.getLocalSN() && retailTradeNew.getPos_ID() == retailTradeOld.getPos_ID() && DatetimeUtil.compareDate(retailTradeNew.getSaleDatetime(), retailTradeOld.getSaleDatetime())) { //POS_SN和POS_ID,SaleDatetime组成的唯一键用于识别是否同一张单
//删除新数据
deleteRetailTrade(retailTradeOld);
//插入新数据
insertRetailTrade(retailTradeNew);
bmOldList.remove(j);
break;
}
}
}
}
}

浙公网安备 33010602011771号