1
votes

I'm pretty new to Spring and Spring Web Flow to be precise. I'm running into the issue of not being able to bind the view with the form on submit :- Here is what I have for code :-

P.s : I don't know what model={} does in the flow XML, but that's what was available in the code already, and changing it to alertForm doesn't change the behavior/

a) JSP

    <form:form name="alertSubmitForm" method="post" id="alertsForm" modelAttribute="alertForm">
            <table class="general">
                <tr>
                    <th>Alert Text
                    </th>
                    <td><form:textarea path="alertText" cols="50" id="alertText" style="padding-top: 11px"></form:textarea>
                    </td>
                    <td><span id="characterCount"></span>/250
                    </td>
                    <td><br/><br/><br/><br/><br/><input id="advancedAlertOptions" type="button" value="More" class="primarybtn" style="float:right;"/></td>
                </tr>
                <tr class="advancedAlertOptions" style="display:none">
                    <th>Active Date
                    </th>
                    <td><form:input path="activeDate" id="activeDate" type="date"/>
                    </td>
                </tr>
                <tr class="advancedAlertOptions"  style="display:none">
                    <th>Expiration Date
                    </th>
                    <td><form:input id="expDate" path="expDate" type="date"/>
                    </td>
                </tr>
                <tr class="advancedAlertOptions" style="display:none">
                    <th>Author
                    </th>
                    <td><form:input id="author" path="author" type="text" disabled="true" value="${author}" />
                    </td>
                </tr>
                <tr class="advancedAlertOptions" style="display:none">
                    <th>Added on
                    </th>
                    <td><form:input id="addedDate" type="date" path="addedDate" disabled="true"/>
                    </td>
                </tr>
            </table>
            <input id="cancelAddAlert" type="button" value="Cancel" class="secondarybtn" style="float:right; margin-left:20px;"/>
            <input id="persistAlert" type="submit" value="Add" class="secondarybtn" style="float:right;" name="_eventId_addAlert"/>
        </form:form>

b) Flow XML

    <view-state id="general" view="editMember/general" model="{}" parent="#abstract-member-view">
        <on-entry>
            <evaluate expression="new com.company.member.alerts.AlertForm()" result="viewScope.alertForm"/>         
        </on-entry>
        <on-render>         
            <evaluate expression="alertManagementService.getAlertsList(partyIdMember)" result="viewScope.alerts" />
        </on-render>        
         <transition on="addAlert" to="general" bind="true" >
            <evaluate expression="alertManagementService.addAlertToMember(alertForm,partyIdMember)" /> 
        </transition>
    </view-state>

c) Service Call

package com.company.member.alerts;

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;

    import org.hibernate.SQLQuery;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import com.company.domain.db.GenericDao;

    @Service("alertManagementService")
    @Transactional(readOnly = true)
    public class AlertManagementServiceImpl implements AlertManagementService {

    @Autowired
    GenericDao dao;
    @Override
    public List<AlertForm> getAlertsList(Long memberId) {
        String a = "SELECT * FROM PARTY_ALERT WHERE PARTY_ID = "+memberId+ " ORDER BY PA_ACTIVE_DATE";
        SQLQuery query = dao.createSQLQuery(a);
        List<Object[]> queryResults = query.list();
        List<AlertForm> results = new ArrayList<AlertForm>();
        for(Object[] arr : queryResults) {
            AlertForm alertForm = new AlertForm();
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd H:m:s");
            try {
                alertForm.setAlertId(Long.valueOf(arr[0].toString()));
                alertForm.setMemberId(Long.valueOf(arr[1].toString()));
                alertForm.setAlertText(arr[2].toString());
                Date acD = df.parse(arr[3].toString());
                alertForm.setActiveDate(acD);
                if(arr[4]!=null) {
                    Date expD = df.parse(arr[4].toString());
                    alertForm.setExpDate(expD);
                }
                alertForm.setAuthor(arr[5].toString());
                Date adD = df.parse(arr[6].toString());
                alertForm.setAddedDate(adD);
                alertForm.setAddedDate(adD);
                alertForm.setActiveDate(acD);
            } 
            catch (ParseException e) {
                e.printStackTrace();
            }
            results.add(alertForm);
        } 
        return results;
    }

    @Override
    public void addAlertToMember(AlertForm alert, Long memberID) {
        Date expDate;
        PartyAlerts partyAlertsDB = new PartyAlerts();
        if(alert.getAlertText()!=null) {
            partyAlertsDB.setAlertText(alert.getAlertText());
            partyAlertsDB.setActiveDate(alert.getActiveDate());
            partyAlertsDB.setMemberId(memberID);
            if((expDate = alert.getExpDate())!=null) {
                partyAlertsDB.setInactiveDate(expDate);
            }
        }
        else { //hardcoding into DB
            partyAlertsDB.setActiveDate(new Date());
            partyAlertsDB.setInactiveDate(new Date());
            partyAlertsDB.setAlertText("This is a hardcoded alert");
            partyAlertsDB.setMemberId(memberID);
        }
        dao.save(partyAlertsDB);
    }
}

d) Form Backing Bean

    package com.company.member.alerts;

    import java.io.Serializable;
    import java.util.Date;


    public class AlertForm  implements Serializable{
    private static final long serialVersionUID = 1L;
    private Long alertId;
    private Long memberId;
    private String alertText;
    private Date activeDate;
    private Date expDate;
    private Date addedDate;
    private String author;

    public AlertForm() {
    }

    public Long getAlertId() {
        return alertId;
    }
    public void setAlertId(Long alertId) {
        this.alertId = alertId;
    }
    public Long getMemberId() {
        return memberId;
    }
    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }
    public String getAlertText() {
        return alertText;
    }
    public void setAlertText(String alertText) {
        this.alertText = alertText;
    }
    public Date getActiveDate() {
        return activeDate;
    }
    public void setActiveDate(Date activeDate) {
        this.activeDate = activeDate;
    }
    public Date getExpDate() {
        return expDate;
    }
    public void setExpDate(Date expDate) {
        this.expDate = expDate;
    }
    public Date getAddedDate() {
        return addedDate;
    }
    public void setAddedDate(Date addedDate) {
        this.addedDate = addedDate;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }


}

The issue is that - when I submit the form - alertForm element are NULL . The getter to get all the alerts on render works as expected.

Any help will be highly appreciated.

1

1 Answers

0
votes

If you are new to SWF why are using advanced features like flow inheritance? what are the contents of the parent flow which contains the reference:

... model="{}" parent="#abstract-member-view">

This is most likely the source of your problem. You need to explicitly define the model attribute to an already initialized POJO in order to bind the form fields correctly to it.

So for testing purposes to simplify initialize a new AlertForm in the flow some where before and OUTSIDE your view-state

....
     <set name="alertFormModel" value="new com.company.member.alerts.AlertForm()"/>
....



 <!-- then when you enter the view-state define it like this: -->


<view-state id="general" view="editMember/general" model="alertFormModel">
....
</view-state>

if this test works then create/implement a Factory pattern for AlertForm to get rid of the ugly 'new' syntax in your flow xml