简体   繁体   中英

Why doesn't model save my data after submitting a form?

My Spring MVC project is kind of a transaction service where you have Clients and list of Transactions. I am using Hibernate as well. I have this client panel in which client sees his balance, previous transactions and is able to to do new transactions. Here is a snippet of my .jsp file

Transfer Data is being passed just fine, but "loggedClient" attribute appears as an empty object with nulls getting passed as values. This only happens after clicking the Submit button and doesn't happen when refreshing the site. The key to solving thi problem may be the loggedClint.toString() which returns: Client [id=0, firstName=null, lastName=null, email=null, balance=0] Any Ideas why this is happening? How can I fix this so after submitting the transaction my "loggedClient" attribute stays filled with client's data ?

<div id="wrapper">
    <div id="header">
        <h2>Welcome ${loggedClient.firstName} ${loggedClient.lastName}</h2>

    </div>
    <header><label class="balancelabel" > Balance: ${loggedClient.balance} </label></header>
</div>
<br><br>
    <fieldset>
        <legend>Transfer Money</legend>
            <form:form action="transferMoney" modelAttribute="transferData" >
                <table>
                    <tbody>
                        <tr>
                            <td><label>Recipients Email:</label></td>
                            <td><form:input path="mail" /></td>
                        </tr>
                        <tr>
                            <td><label>Amount :</label></td>
                            <td><form:input path="amount" /></td>
                        </tr>
                        <tr>
                            <td><label></label></td>
                            <td><input type="submit" value="Send Transfer" class="save" /></td>
                        </tr>
                    </tbody>        
                </table>
            </form:form>
    </fieldset><div id="container">

    <div id="content">

        <table>

            <tr>
                <th>From</th>
                <th>To</th>
                <th>Amount</th>     
                <th>Timestamp</th>
                <!-- <th></th> -->
            </tr>

            <c:forEach var="tempTransfer" items="${transferList}">

                <tr>
                    <td>${tempTransfer.sender.lastName}</td>
                    <td>${tempTransfer.receiver.lastName}</td>
                    <td>${tempTransfer.amount}</td>
                    <td>${tempTransfer.timestamp}</td>


                </tr>

            </c:forEach>

        </table>

    </div>

And here is the Controller code snippet:

@PostMapping("/transferMoney")
public String processTransfer(@ModelAttribute("loggedClient") Client loggedClient, @ModelAttribute("transferData") TransferDataContainer transferData, Model model) {

    Client recipient = clientService.getClient(transferData.getMail());
    System.out.println(loggedClient.toString());
    if(transferData.getAmount() > loggedClient.getBalance()) {
        System.out.println("You cannot send more than you have");
        //System.out.println("You were trying to send : " + transferData.getAmount() +" but you have " +  loggedClient.getBalance());
    } else if(recipient==null) {
        System.out.println("Invalid recepient");
    } else {
        int amount = transferData.getAmount();
        // Updating data
        loggedClient.setBalance(loggedClient.getBalance()-amount);
        recipient.setBalance(recipient.getBalance()+amount);
        Transfer transfer = new Transfer(amount, new Timestamp(System.currentTimeMillis()) , loggedClient, recipient);

        clientService.saveClient(loggedClient);
        clientService.saveClient(recipient);
        transferService.saveTransfer(transfer);

    }
    return "client-logged";

}

I believe I see the problem now. What's happening is the loggedClient in your JSP is not within the form, so when the form is submitted only things in transferData are being sent. If you want to send the loggedClient pieces back, you'll need to fold it in as hidden input fields within transferData.

For example, in your JSP:

<form...>
    <form:hidden path="loggedClient.firstName" value="${loggedClient.firstName"/> 
    <form:hidden path="loggedClient.lastName" value="${loggedClient.lastName"/>
...
</form>

Then in your control, remove the loggedClient parameter. Update your TransferData class to include a loggedClient property, and you should be good to go.

This is happening because your form has only one modelAttribute. When you submit the form only one object is passed, which is transferData. You will forever get the other one null due to the fact that loggedClient is not part of the form.

Anyway even if you will try to pass the loggedClient as form input parameters it won't populate the @ModelAttribute Client, cause the form has already a modelAttribute which is saying "transferData" and you can not add another one there.

If you want to pass the loggedClient information you have to change approach. I suggest to use session for loggedClients and to not pass it page by page with forms.

In case session is not a solution for you and you must use @ModelAttribute you than have to consider to add inside transferData the fields of loggedClient and add them in the form as input parameters (quite bad design to be honest so I dont suggest this)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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