Announcement Announcement Module
Collapse
No announcement yet.
Spring 3.0 formatters not being applied on JSP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 3.0 formatters not being applied on JSP

    Hi Spring experts,

    I have a problem trying to get formatters to be applied when I return a list of my model object. It works when saving/binding the object but not when displaying the objects in a list.

    Here's the scenario.

    Code:
    public class Customer {
        @Numberformat(pattern="#,###.00")
        BigDecimal salary;
    }
    The format is applied when saving. eg

    Code:
    <form:form commandName="customer">
        ...
        <spring:bind path="salary">
            <input type="text" ... value="${status.value}"/>
        </spring:bind>
    </form:form>
    However, when I have List<Customer> and am iterating through each and displaying on a table, I can't get the formatter to apply. eg

    Code:
    <table>
        <c:forEach items="${customers}" var="customer">
            <c:set var="customer" value="${customer}" scope="request"/>
            <tr>
                <td><spring:bind path="customer.salary">${status.value}</spring:bind></td>
            </tr>
        </c:forEach>
    </table>
    I've also tried to wrap the bind in a <form:form> but it also doesn't work. eg

    Code:
    <td>
        <form:form commandName="customer">
            <spring:bind path="salary">${status.value}</spring:bind>
        </form:form>
    </td>
    I'm guessing that's because there isn't a request model object bound to BindingResult.MODEL_KEY_PREFIX + "customer" ... but how do I get one in there when iterating through my List<Customer>?

    Can someone show me where I went wrong here and how I can activate the formatters?

    thanks,
    dave

  • #2
    I found the problem. It is located in HandlerMethodInvoker.updateModelAttributes() which exposes a BindingResult only if the entry in the model satisfies isBindingCandidate(). Collections (and Lists) are excluded so no custom editors/formatters are exposed.

    I have created a simple tag which I wrap my jsp code to create a binder, invoke doBody and then via reflections clear the RequestContext.errorsMaps. I could then use it like so:

    Code:
    <c:forEach items="${customers}" var="customer" varStatus="status">
        <ui:bind var="customer" value="${customer}" pageContext="<%=pageContext%>">
            ....
            <td><spring:bind path="salary">${status.value}</spring:bind></td>
            ....
        </ui:bind>
    </c:forEach>

    My <ui:bind> tag looks something like so:

    Code:
    <%@ attribute name="var" required="true" rtexprvalue="true" %>
    <%@ attribute name="value" required="true" rtexprvalue="true" type="java.lang.Object" %>
    <%@ attribute name="pageContext" required="true" rtexprvalue="true" type="javax.servlet.jsp.PageContext" %>
    
    <spring:nestedPath path="${var}">
        <%
            // create WebDataBinder, do bind and export BindingResult using var as the objectName and value as the target
            // ...
        %>
        <jsp:doBody/>
        <%
            RequestContext requestContext = (RequestContext) pageContext.getAttribute(RequestContextAwareTag.REQUEST_CONTEXT_PAGE_ATTRIBUTE);
            if (requestContext != null) {
                // use reflections to get to errorsMap, making it accessible before setting it's value (it is declared private)
                // errors map has to be updated because it caches entries
                Map errorsMap = (Map) ReflectionUtils.getFieldValue(requestContext, "errorsMap");
                if (errorsMap != null) {
                    errorsMap.remove(var);
                }
            }
        %>
    </spring:nestedPath>
    Not sure how many rules of design this violates, but it works. Now I can leverage my custom editors for lists that are returned from the Controller.
    Last edited by davoz; Feb 24th, 2010, 03:59 PM.

    Comment


    • #3
      This is old now but still shows up in Google first search page. Using <spring:eval/> tag in 3.1 looks like the way to go. I have documented how to use the Formatters and how to enhance the current @NumberFormat in http://thinkinginsoftware.blogspot.c...on-driven.html

      Hopefully the Spring team will make some enhancements like the ones I am proposing for example for Rounding.

      Comment

      Working...
      X