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;
                    }
                }
            }
        }
    }

 

posted @ 2021-12-22 14:57  Boxin-kim  阅读(198)  评论(0)    收藏  举报
Web Analytics
Guang Zhou Boxin