How do I collect a list of ClientMapping objects from a JSP using Spring 6 and JSTL? - Stack Overflow

admin2025-05-01  0

I have a List in a controller that has one ClientMapping Object. I am trying to gather that data in the JSP form and then send back to another controller.

Here is the controller code

@RequestMapping("/chooseMappingValues")
    public ModelAndView chooseMappingValues() {
        ModelAndView mav = new ModelAndView();
        
        ClientMapping clientMappingChoices = new ClientMapping();
        clientMappingChoices.setMappingName("MyMapping");
        clientMappingChoices.setSchemaNameCoderepeaper("reference_tables");
        List<ClientMapping> cmList = new ArrayList<ClientMapping>();
        cmList.add(clientMappingChoices);
        
        Map<String, String> databases = lookupService.getLookup("DatabaseVendor");
        Map<String, String> tableNames = lookupService.getLookup("TableName");
        mav.addObject("tableNames", tableNames);
        mav.addObject("databaseVendor", databases);
        mav.addObject("message", "Enter Mapping Name.  Choose Target Database Type, Schema Name and Table for Mapping.");
        mav.addObject("clientMappingChoices", cmList);
        mav.setViewName("mappingtool/chooseMappingValues");

        return mav;
    }

ANd here is the JSP

                <div class="card-body justify-content-md-center"
                    style="background-color: darkgray;">
                    <form:form action="${pageContext.request.contextPath}/mappingtool/gatherMappingDetails"
                        method="POST" modelAttribute="clientMappingChoices">
                        <c:forEach items="${clientMappingChoices}" var="cm" varStatus="status">
                            <div class="table-responsive">
                                <table
                                    class="table table-responsive table-striped table-hover table-sm"
                                    id="viewTable">
                                    <tbody>
                                        <tr>
                                            <td colspan="2" class="fw-bolder justify-content-md-center"><h2
                                                    class="text-primary">${message}</h2>
                                        <tr>
                                            <td class="fw-bolder"><label for="mappingName"
                                                class="form-label"> Client Mapping Name:</label> <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:input
                                                    class="form-control form-control-sm" id="mappingName"
                                                    path="${cm}.mappingName" cssStyle="width:200px;" /> <form:errors
                                                    
path="${cm}.mappingName" /></td>
                                        <tr>
                                            <td>&nbsp;</td>
                                            <td><input class="btn btn-danger my-2 my-sm-0" id="save"
                                                type="submit" value="Save" /></td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </c:forEach>
                    </form:form>

I have tried to setup the path of the spring form a bunch of ways but can't seem to get the syntax correct.

Here is the error message from the code above:

2025-01-02 16:17:45,985 TRACE o.s.w.s.DispatcherServlet [http-nio-80-exec-5] Failed to complete request
org.apache.jasper.JasperException: An exception occurred processing [/WEB-INF/pages/mappingtool/chooseMappingValues.jsp] at line [151]

148:                                            class="form-label"> Client Mapping Name:</label> <label
149:                                            class="text-danger">&nbsp;Required</label></td>
150:                                        <td class="fw-bolder">
151:                                            <form:input class="form-control form-control-sm" id="mappingName"
152:                                                path="${cm}.mappingName" cssStyle="width:200px;" /> <form:errors
153:                                                path="${cm}.mappingName" /></td>
154:                                    </tr>

Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'ClientMapping [idPk=null, clientId=null, mappingName=MyMapping, schemaNameClient=null, schemaNameCoderepeaper=reference_tables, tableNameClient=null, tableNameCodereaper=null, columnNameClient=null, columnNameCodereaper=null, dataType=null, created=null, createdBy=null, updated=null, updatedBy=null]' of bean class [java.util.ArrayList]: Bean property 'ClientMapping [idPk=null, clientId=null, mappingName=MyMapping, schemaNameClient=null, schemaNameCoderepeaper=reference_tables, tableNameClient=null, tableNameCodereaper=null, columnNameClient=null, columnNameCodereaper=null, dataType=null, created=null, createdBy=null, updated=null, updatedBy=null]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:627) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:856) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:831) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:615) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:158) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178) ~[spring-webmvc-6.1.13.jar:6.1.13]

I have a List in a controller that has one ClientMapping Object. I am trying to gather that data in the JSP form and then send back to another controller.

Here is the controller code

@RequestMapping("/chooseMappingValues")
    public ModelAndView chooseMappingValues() {
        ModelAndView mav = new ModelAndView();
        
        ClientMapping clientMappingChoices = new ClientMapping();
        clientMappingChoices.setMappingName("MyMapping");
        clientMappingChoices.setSchemaNameCoderepeaper("reference_tables");
        List<ClientMapping> cmList = new ArrayList<ClientMapping>();
        cmList.add(clientMappingChoices);
        
        Map<String, String> databases = lookupService.getLookup("DatabaseVendor");
        Map<String, String> tableNames = lookupService.getLookup("TableName");
        mav.addObject("tableNames", tableNames);
        mav.addObject("databaseVendor", databases);
        mav.addObject("message", "Enter Mapping Name.  Choose Target Database Type, Schema Name and Table for Mapping.");
        mav.addObject("clientMappingChoices", cmList);
        mav.setViewName("mappingtool/chooseMappingValues");

        return mav;
    }

ANd here is the JSP

                <div class="card-body justify-content-md-center"
                    style="background-color: darkgray;">
                    <form:form action="${pageContext.request.contextPath}/mappingtool/gatherMappingDetails"
                        method="POST" modelAttribute="clientMappingChoices">
                        <c:forEach items="${clientMappingChoices}" var="cm" varStatus="status">
                            <div class="table-responsive">
                                <table
                                    class="table table-responsive table-striped table-hover table-sm"
                                    id="viewTable">
                                    <tbody>
                                        <tr>
                                            <td colspan="2" class="fw-bolder justify-content-md-center"><h2
                                                    class="text-primary">${message}</h2>
                                        <tr>
                                            <td class="fw-bolder"><label for="mappingName"
                                                class="form-label"> Client Mapping Name:</label> <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:input
                                                    class="form-control form-control-sm" id="mappingName"
                                                    path="${cm}.mappingName" cssStyle="width:200px;" /> <form:errors
                                                    
path="${cm}.mappingName" /></td>
                                        <tr>
                                            <td>&nbsp;</td>
                                            <td><input class="btn btn-danger my-2 my-sm-0" id="save"
                                                type="submit" value="Save" /></td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </c:forEach>
                    </form:form>

I have tried to setup the path of the spring form a bunch of ways but can't seem to get the syntax correct.

Here is the error message from the code above:

2025-01-02 16:17:45,985 TRACE o.s.w.s.DispatcherServlet [http-nio-80-exec-5] Failed to complete request
org.apache.jasper.JasperException: An exception occurred processing [/WEB-INF/pages/mappingtool/chooseMappingValues.jsp] at line [151]

148:                                            class="form-label"> Client Mapping Name:</label> <label
149:                                            class="text-danger">&nbsp;Required</label></td>
150:                                        <td class="fw-bolder">
151:                                            <form:input class="form-control form-control-sm" id="mappingName"
152:                                                path="${cm}.mappingName" cssStyle="width:200px;" /> <form:errors
153:                                                path="${cm}.mappingName" /></td>
154:                                    </tr>

Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'ClientMapping [idPk=null, clientId=null, mappingName=MyMapping, schemaNameClient=null, schemaNameCoderepeaper=reference_tables, tableNameClient=null, tableNameCodereaper=null, columnNameClient=null, columnNameCodereaper=null, dataType=null, created=null, createdBy=null, updated=null, updatedBy=null]' of bean class [java.util.ArrayList]: Bean property 'ClientMapping [idPk=null, clientId=null, mappingName=MyMapping, schemaNameClient=null, schemaNameCoderepeaper=reference_tables, tableNameClient=null, tableNameCodereaper=null, columnNameClient=null, columnNameCodereaper=null, dataType=null, created=null, createdBy=null, updated=null, updatedBy=null]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:627) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:856) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:831) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:615) ~[spring-beans-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:158) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178) ~[spring-webmvc-6.1.13.jar:6.1.13]
Share Improve this question asked Jan 2 at 21:20 charles didonatocharles didonato 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

I resolved this by doing the following:

created a top level object that has a List of ClientMpping objects.

Pojo below

public class ClientMappingForm {
    private List<ClientMapping> dynamicRow =
            LazyList.decorate(new ArrayList<ClientMapping>(), FactoryUtils.instantiateFactory(ClientMapping.class));

    public ClientMappingForm() {
        // TODO Auto-generated constructor stub
    }

    public List<ClientMapping> getDynamicRow() {
        return dynamicRow;
    }

    public void setDynamicRow(List<ClientMapping> dynamicRow) {
        this.dynamicRow = dynamicRow;
    }
}

Controller for this as follows

@RequestMapping("/chooseMappingValues")
public ModelAndView chooseMappingValues() {
    ModelAndView mav = new ModelAndView();
    
    ClientMappingForm form = new ClientMappingForm();
    ClientMapping cm = new ClientMapping();
    cm.setMappingName("MyMapping");
    cm.setSchemaNameCoderepeaper("reference_tables");
    List<ClientMapping> cmList = new ArrayList<ClientMapping>();
    cmList.add(cm);
    form.setDynamicRow(cmList);
    
    Map<String, String> databases = lookupService.getLookup("DatabaseVendor");
    Map<String, String> tableNames = lookupService.getLookup("TableName");
    mav.addObject("tableNames", tableNames);
    mav.addObject("databaseVendor", databases);
    mav.addObject("message", "Enter Mapping Name.  Choose Target Database Type, Schema Name and Table for Mapping.");
    mav.addObject("clientMappingForm", form);
    mav.setViewName("mappingtool/chooseMappingValues");

    return mav;
}

And finally the JSP

<div class="card-body justify-content-md-center"
                    style="background-color: darkgray;">
                    <form:form action="${pageContext.request.contextPath}/mappingtool/gatherMappingDetails"
                        method="POST" modelAttribute="clientMappingForm">                   
                            <div class="table-responsive">
                                <table class="table table-responsive table-striped table-hover table-sm" id="viewTable">
                                    <tbody>
                                        <tr>
                                            <td colspan="2" class="fw-bolder justify-content-md-center"><h2
                                                    class="text-primary">${message}</h2>
                                        <tr>
                                            <td class="fw-bolder"><label for="mappingName"
                                                class="form-label"> Client Mapping Name:</label> <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:input
                                                    class="form-control form-control-sm" id="mappingName"
                                                    path="dynamicRow[0].mappingName" cssStyle="width:200px;" /> <form:errors
                                                    path="dynamicRow[0].mappingName" /></td>
                                        </tr>
                                        <tr>
                                            <td class="fw-bolder"><label for="user.lastname"
                                                class="form-label">Client Schema Name:</label> <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:input
                                                    class="form-control form-control-sm" id="schemaNameClient"
                                                    path="dynamicRow[0].schemaNameClient" cssStyle="width:200px;" /> <form:errors
                                                    path="dynamicRow[0].schemaNameClient" /></td>
                                        </tr>
                                        <tr>
                                            <td class="fw-bolder">Table Type: <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:select
                                                    id="tableNameCodereaper" path="dynamicRow[0].tableNameCodereaper">
                                                    <form:option value="" label="--- Select ---" />
                                                    <form:options items="${tableNames}" />
                                                </form:select> <form:errors path="dynamicRow[0].tableNameCodereaper" /></td>
                                        </tr>
                                        <tr>
                                            <td class="fw-bolder">Database Type: <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:select id="databaseVendor"
                                                    path="dynamicRow[0].databaseVendor">
                                                    <form:option value="" label="--- Select ---" />
                                                    <form:options items="${databaseVendor}" />
                                                </form:select> <form:errors path="dynamicRow[0].databaseVendor" /></td>
                                        </tr>
                                        <tr>
                                            <td class="fw-bolder">Client Tablename: <label
                                                class="text-danger">&nbsp;Required</label></td>
                                            <td class="fw-bolder"><form:input
                                                    class="form-control form-control-sm" id="tableNameClient"
                                                    path="dynamicRow[0].tableNameClient" cssStyle="width:200px;" /> <form:errors
                                                    path="dynamicRow[0].tableNameClient" /></td>
                                        </tr>
                                        <tr>
                                            <td>&nbsp;</td>
                                            <td><input class="btn btn-danger my-2 my-sm-0" id="save"
                                                type="submit" value="Save" /></td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                    </form:form>
                    <div>
                        <jsp:directive.include
                            file="/WEB-INF/sitemesh-common/empireidsfooter.jsp" />
                    </div>
                </div>
转载请注明原文地址:http://anycun.com/QandA/1746096313a91613.html