Results 1 to 2 of 2

Thread: Spring 3 mvc and freemarker: @spring.showErrors throws a "get(errorMessages) failed..

  1. #1
    Join Date
    May 2011
    Posts
    2

    Default Spring 3 mvc and freemarker: @spring.showErrors throws a "get(errorMessages) failed..

    I have experience with Spring MVC with JSPs and am now working on project that uses Freemarker instead, and for the life of me I cannot get errors to display on my web pages via freemarker. I have two problems:
    1) My validation errors aren't seen in the freemarker ftl (it shows I have zero errors)
    2) Even though my ftl model reports zero errors, if I add spring error support to my ftl the freemarker parser throws an exception if the spring validator added an error.

    I'm hoping I'm simply doing something silly that a kind soul can point out to me. Here's the summary followed by code snippets :
    - I'm using Spring mvc 3.0.5.RELEASE and Freemarker 2.3.15

    - I have a controller and a validator, and my validator correctly adds an error and that error is seen in my controller's POST method's BindingResult. I add the BindingResult's model to my ModelAndView.

    - My freemarker ftl binds correctly to my model object, i.e. on the GET it displays the correct values from the model, and on the POST any values I've entered are present in controller's POST method's model object.

    - When I put a breakpoint in my controller's POST method just before it returns the ModelAndView, my ModelAndView contains an org.springframework.validation.BeanPropertyBinding Result object with key "org.springframework.validation.BindingResult.paym entInfo" (my command object is called "paymentInfo"). Here's the full object toString fwiw:
    Code:
    org.springframework.validation.BeanPropertyBindingResult: 1 errors
    Field error in object 'paymentInfo' on field 'paymentFields.creditCardNumber': rejected value []; codes [Credit card number must not be blank.paymentInfo.paymentFields.creditCardNumber,Credit card number must not be blank.paymentFields.creditCardNumber,Credit card number must not be blank.creditCardNumber,Credit card number must not be blank.java.lang.String,Credit card number must not be blank]; arguments []; default message [null]
    controller snippet:
    Code:
    @RequestMapping(value = "/processpayment", method = RequestMethod.POST)
    public ModelAndView processPayment(@ModelAttribute("paymentInfo") @Valid PaymentInfo paymentInfo, BindingResult result,
        SessionStatus status, HttpServletRequest request) {
    
      final String hapiAccountName = paymentInfo.getAccountName();
      String hapiUserName = null;
      HapiSession session = null;
      ModelAndView mav = new ModelAndView();
      try {
        
        if (result.hasErrors()) {
          ModelAndView mavErr = new ModelAndView(getViewName(paymentInfo), "paymentInfo", paymentInfo);
          mavErr.addAllObjects(result.getModel());
          return mavErr;
        }
    validator snippet:
    Code:
    @Override
    public void validate(Object target, Errors errors) {
      PaymentInfo pi = (PaymentInfo) target;
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "paymentFields.creditCardNumber", "Credit card number must not be blank");
    }
    freemarker ftl snippet:
    Code:
    <@spring.bind "paymentInfo" />
    <#if spring.status.error>
      errors<br>
    </#if>                                    
    size=${spring.status.errorMessages?size}<br>
    <@spring.bind "paymentInfo.paymentFields.creditCardNumber" />
    <div class="cart-formcol2"><input id="paymentInfoForm_creditCardNumber" name="paymentFields.creditCardNumber" class="cart-input" type="text" value=""/> </div>   
    <@spring.showErrors "br"/>
    You'll see I have some debugging code in my ftl. The spring.status.error evaluates to false and spring.status.errorMessages?size evaluates to zero. However adding
    Code:
    <@spring.showErrors "br"/>
    causes the freemarker parser to fail with this error:
    Code:
    get(errorMessages) failed on instance of org.springframework.web.servlet.support.BindStatus The problematic instruction: ---------- ==> list status.errorMessages as error [on line 330, column 5 in spring.ftl] in user-directive spring.showErrors [on line 98, column 45 in com/homeaway/hapiservice/paymentform/vr/v1.ftl] in user-directive payment.paymentForm [on line 31, column 29 in com/homeaway/hapiservice/paymentform/vr/v1.ftl] ---------- Java backtrace for programmers: ---------- freemarker.template.TemplateModelException: get(errorMessages) failed on instance of org.springframework.web.servlet.support.BindStatus at freemarker.ext.beans.BeanModel.get(BeanModel.java:223) at 
    (etc.)
    I've also tried using the example directly from the spring 3.0 docs:
    Code:
    <@spring.bind "paymentInfo.paymentFields.creditCardNumber" /> 
    <input type="text" 
    name="${spring.status.expression}" 
    value="${spring.status.value?default("")}" /><br>
    <#list spring.status.errorMessages as error> <b>${error}</b> <br> </#list>
    While that example correctly binds input values to my model object, it throws the same "get(errorMessages) failed..." exception upon parsing.

    Interestingly I don't get a parse exception if the validator doesn't add any errors. This is odd to me because when I have validation errors ${spring.status.errorMessages?size} still evaluates to zero (why doesn't it report the number of errors I have?) while <#list spring.status.errorMessages as error> does throw an error. If ${spring.status.errorMessages?size} then I would think the <#list> would not even evaluate anything. And of course I don't know why ${spring.status.errorMessages?size} would be zero when I can see a BindingResult. And why does one reference to spring.status.errorMessages cause a parse exception while the other doesn't?

    I've looked at this for several hours and am stumped. For a jsp in Spring mvc, displaying errors has always been easy for me, but I'm clearly missing something for Spring + Freemarker since no one else on the web seems to report this problem (except for one post in an Asian language I couldn't understand). I'd be most appreciative if anyone has suggestions on where I might look to figure out what I'm doing wrong.

    Thanks

  2. #2
    Join Date
    May 2011
    Posts
    2

    Default

    I figured it out, and I was indeed doing something stupid: in my validator the second argument to ValidationUtils.rejectIfEmptyOrWhitespace should be a message property name, not a string to be displayed. I've used properties on my previous Spring projects for jsps, but for some reason I wasn't thinking I wrote this validator. It would be nice if Spring provided a more helpful error message along the lines of "This message property cannot be found: Credit card number must not be blank" rather than throwing a cryptic "get(errorMessages) failed..." error. I hope this helps someone else.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •