繁体   English   中英

将包含另一个对象数组的 javascript object 传递给 localStorage,然后使用 ajax 传递给 java servlet

[英]Passing javascript object containing another array of objects to localStorage and then to java servlet using ajax

我正在尝试弄清楚如何在本地存储中存储一个 javascript object,如果可能的话,它有一些项目以及一个对象数组。 然后从本地存储中提取数据并使用 ajax 发送到 java servlet,然后从 java HttpServletRequest 中提取数据。 这是我写的一些代码。 将整个代码库放在这里有点太复杂了。 我有多个用户完成的 forms,当他们在 forms 之间移动时,我将输入的数据存储到本地存储中。

const object = localStorage.getItem(scenarioName);
let scenarioObject = JSON.parse(object);

if (formIsValid) {
            scenarioObject.SUPER_BALANCE = 420000;
            scenarioObject.SUPER_INVESTMENT_FEES = 0.14;
            scenarioObject.SUPER_ADMIN_FEES = 120;
            scenarioObject.LIFE_INSURANCE = 200000;
            scenarioObject.ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION = 1500;

        let objectString = JSON.stringify(scenarioObject);
        localStorage.setItem(scenarioName, objectString);

}

要从本地存储中提取数据,我执行以下操作:

const object = localStorage.getItem(activeScenario);
    const jsonString = JSON.parse(object);

    const yourSuperBalance = jsonString.SUPER_BALANCE;
    $("#your-super-balance").val(yourSuperBalance);

    const yourInvestmentFees = jsonString.SUPER_INVESTMENT_FEES;
    $("#super-investment-fees").val(yourInvestmentFees);

    const yourSuperAdminFees = jsonString.SUPER_ADMIN_FEES;
    $("#super-admin-fees").val(yourSuperAdminFees);

    const yourInsurance = jsonString.LIFE_INSURANCE;
    $("#life-insurance").val(yourInsurance);

    const yourAnnualSuperContribution = jsonString.ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION;
    $("#your-annual-lump-sum-super-contribution").val(yourAnnualSuperContribution);

这一切都很好,但现在我想从表中添加一个对象数组。 我想不出添加这个的方法,所以我最终在本地存储中存储了两个项目。 一个用于所有表单数据,一个用于表格数据。 我不喜欢这种方法,但无法让它发挥作用。 这是我制作表格的方式:

function getSuperContributionsTableDataString(table) {
    let yourSuperContributionsTableData = [];
    let jsonData;
    // commence for loop at 1 because the first row will be the header row and we want to skip that
    for (let i = 1; i < table.rows.length; i++) {
        let row = table.rows[i];
        // first check all cells in row have a value, if not ignore
        if (row.cells[0].innerText !== "" && row.cells[1].innerText !== "" && row.cells[2].innerText !== "") {
            // As we are pushing the last element pushed becomes the first element in the array
            // therefore, we push the before or after tax first and age last
            jsonData = {};
            jsonData[SUPER_TAXATION_CONTRIBUTION] = row.cells[2].innerText;
            jsonData[SUPER_AMOUNT_CONTRIBUTION] = row.cells[1].innerText;
            jsonData[SUPER_AGE_CONTRIBUTION] = row.cells[0].innerText;
            yourSuperContributionsTableData.push(jsonData);
        }
    }
    return JSON.stringify(yourSuperContributionsTableData);
}
let superContributionsTableDataString = getSuperContributionsTableDataString(
                document.getElementById("your-extra-super-contributions-table"));

localStorage.setItem(scenarioName+ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION, superContributionsTableDataString);

这一切都有效,但后来我不得不弄清楚如何使用 ajax 将这些数据发送到服务器。没有表格,一切正常,如下所示:

function sendScenarioDetailsToServer() {
    let activeScenario = localStorage.getItem(ACTIVE_SCENARIO_KEY);
    let item = localStorage.getItem(activeScenario);
    let passedData = JSON.parse(item);

    
    $.ajax({
        type: "POST",
        url: "ScenarioServlet",
        data: passedData,
        success: function (data) {
            const SUCCESS_INT = data.length - 1;
            if (data[SUCCESS_INT].SUCCESS === FAIL) {
                displayPopupMessage("Error saving scenario ", "Save Scenario");
            }else {
                displayResult();
            }

        },
        error: function (error, status) {
            console.log(`Error ${error}`);
            const stackTrace = getStackTrace();
            const message = "An error occurred sending your data to the server for calculation. ";
            displayPopupMessage(message, "Server Error.", stackTrace);
        }
    });

}

我按如下方式修改了这个 function 以添加表数据,java servlet 代码中的所有内容都出错了。

function sendScenarioDetailsToServer() {
    let activeScenario = localStorage.getItem(ACTIVE_SCENARIO_KEY);
    let item = localStorage.getItem(activeScenario);
    let passedData = JSON.parse(item);

    // superannuation table
    const superTable = activeScenario+ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION;

    // this is already stringified
    const superTableItem = localStorage.getItem(superTable);
    const superTableData = '&' + ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION + "=" + superTableItem;

    const formData = passedData + superTableData;
    console.log("formData " + formData);


    $.ajax({
        type: "POST",
        url: "ScenarioServlet",
        data: passedData + superTableData,
        success: function (data) {
            const SUCCESS_INT = data.length - 1;
            if (data[SUCCESS_INT].SUCCESS === FAIL) {
                // TODO display messages
                displayPopupMessage("Error saving scenario ", "Save Scenario");
            }else {
                displayResult();
            }
        },
        error: function (error, status) {
            console.log(`Error ${error}`);
            const stackTrace = getStackTrace();
            const message = "An error occurred sending your data to the server for calculation. ";
            displayPopupMessage(message, "Server Error.", stackTrace);
        }
    });

}

谁能建议如何最好地将 javascript object 存储在本地存储中,该存储在 object 中有一个项目,这是一个表的对象数组? 我如何将它存储在本地存储中,从本地存储中检索它,使用 ajax 将它发送到 java servlet,然后从 HttpServletRequest 中检索它。 任何帮助将不胜感激。

我想出了一种方法来做到这一点。 我将充分说明情况,然后再说明我对问题的解决办法。 不确定这是否是最佳解决方案,但它确实有效。 情况是我有多个 forms,用户在其中输入数据进行计算,包括数据表。 我想将此数据存储在本地存储中,以便下次用户使用该网站时进行检索。 计算在服务器上的 Java 中完成,因此当用户单击“计算”之类的内容时,本地存储中的数据将发送到服务器以执行计算并将结果发送回。 我需要存储一个 javascript object 包含一些元素和一个表,所以基本上是一个 javascript object 里面有一个数组。

从表中收集数据

function getSuperContributionsTableDataString(table) {
    let yourSuperContributionsTableData = [];
    let jsonData;
    // commence for loop at 1 because the first row will be the header row and we want to skip that
    for (let i = 1; i < table.rows.length; i++) {
        let row = table.rows[i];
        // first check all cells in row have a value, if not ignore
        if (row.cells[0].innerText !== "" && row.cells[1].innerText !== "" && row.cells[2].innerText !== "") {
            // As we are pushing the last element pushed becomes the first element in the array
            // therefore, we push the before or after tax first and age last
            jsonData = {};
            jsonData[SUPER_TAXATION_CONTRIBUTION] = row.cells[2].innerText;
            jsonData[SUPER_AMOUNT_CONTRIBUTION] = row.cells[1].innerText;
            jsonData[SUPER_AGE_CONTRIBUTION] = row.cells[0].innerText;
            yourSuperContributionsTableData.push(jsonData);
        }
    }
    return yourSuperContributionsTableData;
}

我最初出错的地方是我对数组进行了字符串化。 由于整个 javascript object 将被字符串化,因此这是不必要的。

创建 javascript object 并存储在本地存储中第一步是从本地存储中提取项目,以使用来自用户的新数据对其进行更新。 请注意,我们必须解析 object,因为它最初是字符串化的。 其次将用户输入的数据设置为 javascript object。您会注意到上面调用了 function 来检索表数据。 该表数据设置为javascript object中的键值对。

const scenarioName = localStorage.getItem(ACTIVE_SCENARIO_KEY);
const object = localStorage.getItem(scenarioName);
let scenarioObject = JSON.parse(object);
isValid = validateYourSuperannuationForm();
if (isValid) {
            let superContributionsTableDataString = getSuperContributionsTableDataString(
                document.getElementById("your-extra-super-contributions-table"));

            scenarioObject.SUPER_BALANCE = $("#your-super-balance").val();
            scenarioObject.SUPER_INVESTMENT_FEES = $("#super-investment-fees").val();
            scenarioObject.SUPER_ADMIN_FEES = $("#super-admin-fees").val();
            scenarioObject.LIFE_INSURANCE = $("#life-insurance").val();
            scenarioObject.ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION = $("#your-annual-lump-sum-super-contribution").val();
            scenarioObject.EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA = superContributionsTableDataString;

            let objectString = JSON.stringify(scenarioObject);
            localStorage.setItem(scenarioName, objectString);
        }

将本地存储中的项目发送到服务器我发现尝试将整个 javascript object 字符串化导致服务器出现问题。 我必须做的是为要发送到服务器的 formData 创建一个新的 object,但是我必须只对表数据进行字符串化,而不是整个 object。我必须从本地存储中检索每个项目并将其设置在 formData 上object 传递给服务器。

function sendScenarioDetailsToServer() {
    const activeScenario = localStorage.getItem(ACTIVE_SCENARIO_KEY);
    const item = localStorage.getItem(activeScenario);
    const scenarioObject = JSON.parse(item);

    // We must do this because if superContributionsTableData == "" and we then stringify this it will
    // end up with a value of """", which will cause an error.
    const superContributionsTableData = scenarioObject.EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA;
    let superContributionsTableDataString = "";
    if (superContributionsTableData !== ""){
        superContributionsTableDataString = JSON.stringify(superContributionsTableData);
    }
    const formData = {
        SCENARIO_NAME: scenarioObject.SCENARIO_NAME,
        DATE_OF_BIRTH: "",
        IS_SINGLE:  scenarioObject.IS_SINGLE,
        IS_RETIRED: scenarioObject.IS_RETIRED,
        RETIREMENT_DATE: scenarioObject.RETIREMENT_DATE,
        IS_HOMEOWNER: scenarioObject.IS_HOMEOWNER,
        FORTNIGHTLY_RENT: scenarioObject.FORTNIGHTLY_RENT,
        DATE_RENT_CEASES: scenarioObject.DATE_RENT_CEASES,
        IS_SINGLE_AND_SHARING: scenarioObject.IS_SINGLE_AND_SHARING,
        SPOUSE_DATE_OF_BIRTH: scenarioObject.SPOUSE_DATE_OF_BIRTH,
        IS_SPOUSE_RETIRED: scenarioObject.IS_SPOUSE_RETIRED,
        SPOUSE_RETIREMENT_DATE: scenarioObject.SPOUSE_RETIREMENT_DATE,
        SUPER_BALANCE: scenarioObject.SUPER_BALANCE,
        SUPER_INVESTMENT_FEES: scenarioObject.SUPER_INVESTMENT_FEES,
        SUPER_ADMIN_FEES: scenarioObject.SUPER_ADMIN_FEES,
        LIFE_INSURANCE: scenarioObject.LIFE_INSURANCE,
        ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION: scenarioObject.ANNUAL_LUMP_SUM_SUPER_CONTRIBUTION,
        EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA: superContributionsTableDataString
}
$.ajax({
        type: "POST",
        url: "ScenarioServlet",
        data: formData,

        success: function (data) {
        // do stuff here

       {
},
        error: function (error, status) {
            console.log(`Error ${error}`);
            const stackTrace = getStackTrace();
            const message = "An error occurred sending your data to the server for calculation. ";
            displayPopupMessage(message, "Server Error.", stackTrace);
        }
    });

在 Java Servlet 中,然后从传递给 doPost 方法的 HttpServletRequest 中提取数据。 它通过调用 HttpServletRequest.getParameter 以通常的方式检索。 转换表数据稍微复杂一些,因为它是一个已转换为字符串的数组。 我包括该代码的摘录,以防它对某人有用。

       ArrayList<LumpSumSuperContribution> superContributionsList = new ArrayList<>();
        String superContributionsTableData = request.getParameter(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA);
       // Array superContributionsArray = request.getParameter(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA);
        JSONObject superContributionsMessage = new JSONObject();
        boolean errorOccurred = false;
        if (superContributionsTableData != null && superContributionsTableData.length() > 0) {
            try {
                JSONArray superContributionsArray = new JSONArray(superContributionsTableData);
                int i = 0;
                while (i < superContributionsArray.length()) {
                    JSONObject contributionObj = (JSONObject) superContributionsArray.get(i);
                    String ageString = (String) contributionObj.get(SUPER_AGE_CONTRIBUTION);
                    Validator.WholeNumberResult result6 = Validator.validateMandatoryWholeNumber(ageString, 18, 99,
                            "Lump Sum Super Contribution age for row " + (i + 1));
                    if (!result6.getErrorMessage().equals(SUCCESS)) {
                        superContributionsMessage.put(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA, result6.getErrorMessage());
                        messageArray.put(superContributionsMessage);
                        errorOccurred = true;
                        break;
                    }
                    Integer age = result6.getNumber();
String contributionAmountString = (String) contributionObj.get(SUPER_AMOUNT_CONTRIBUTION);
                    Validator.WholeNumberResult result7 = Validator.validateMandatoryWholeNumber(
                            contributionAmountString, 1, 9999999,
                            "Lump Sum Super Contribution amount for row " + (i + 1));
                    if (!result7.getErrorMessage().equals(SUCCESS)) {
                        superContributionsMessage.put(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA, result7.getErrorMessage());
                        messageArray.put(superContributionsMessage);
                        errorOccurred = true;
                        break;
                    }
                    Integer amount = result7.getNumber();

                    String beforeAfterTaxString = (String) contributionObj.get(SUPER_TAXATION_CONTRIBUTION);
                    Validator.TextResult result8 = Validator.validateMandatoryText(beforeAfterTaxString,
                            "Lump Sum Super Contribution Before or After Tax for row " + (i + 1), 5, 6);
                    if (!result8.getErrorMessage().equals(SUCCESS)) {
                        superContributionsMessage.put(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA, result8.getErrorMessage());
                        messageArray.put(superContributionsMessage);
                        errorOccurred = true;
                        break;
                    }
                    String beforeAfterTax = result8.getText();
LumpSumSuperContribution superContribution = new LumpSumSuperContribution(age, amount, false,
                            LumpSumSuperContribution.YOUR_CONTRIBUTION, beforeAfterTax);

                    superContributionsList.add(superContribution);

                    i++;
                }
                if (!errorOccurred) {
                    scenario.setAllYourSuperContributions(superContributionsList);
                    //  superContributionsMessage.put(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA, SUCCESS);
                } else {
                    fail = true;
                    superContributionsMessage.put(EXTRA_SUPER_CONTRIBUTIONS_TABLE_DATA, FAIL);
                    messageArray.put(superContributionsMessage);
                }

            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
        }else {
            scenario.setAllYourSuperContributions(null);
        }
}

概括

  1. 创建一个 javascript 数组。 然后循环遍历表数据并为表的每一行创建一个 javascript object 并推入数组。
  2. 创建或检索存储在本地存储中的 javascript object。 如果已经在本地存储中,则必须使用 JSON.parse(object) 解析此 object。
  3. 设置用户输入的object的详细信息。
  4. 将 javascript 数组字符串化,将字符串作为键值对添加到 object 中。
  5. 要将数据发送到服务器,请从本地存储中检索项目并解析项目以从中提取详细信息。
  6. 在新创建的 formData object 上设置提取的详细信息。
  7. 将表数据字符串化,在formData中设置为键值对。
  8. 使用 ajax 将数据发布到服务器。

我希望这对将来的人有帮助。 我花了一段时间尝试不同的事情来找到一种方法让它发挥作用。 如果有人有更好的解决方案,请发布。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM