0

Parts of the (Java, Spring-mvc, JSP) Form input is checked by Javascript. The rest is done by a custom Validator. The problem is when the Javascript validation is prevented, such an error may be printed:

Failed to convert property value of type java.lang.String to required type java.lang.Long for property xxx; nested exception is java.lang.NumberFormatException: For input string: "x"

Is there a better way to deal with the conversion itself. When the Java-validator runs it already encounters the conversion error - or is there a possibility to check before that?


edit: the code of the Binder within the Controller..

@InitBinder
public void initBinder(WebDataBinder binder) {
   SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
   dateFormat.setLenient(false);

   binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
   binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));
}

but its really just standard functionality (org.springframework.beans.propertyeditors.CustomNumberEditor) and I thought there has to be a simple solution, since it seems like a common thing to have a Long Object backing some imput field and trying to get no exception out of it (or catching that one)..

2 Answers2

2

Seems that you need to implement a binder in your controller to convert from String to Long. See if this thread helps, it gives you to code to convert String to Long.

Update

binder.registerCustomEditor(Long.class, "myFieldName", new  PropertyEditorSupprt(){
    @Override
    public void setValue(Object value) {
        if(value instanceof String)
           super.setValue(new Long(value));      
    }

});
Community
  • 1
  • 1
Ali
  • 12,354
  • 9
  • 54
  • 83
  • I did that (implement a binder), the problem is that binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true)); already throws the exception as it gets a String. I thought there might be something to do beforhand, or to somehow override the Exception by a specific Message. – definitely undefinable Sep 09 '11 at 10:29
  • can you post your code for the Controller, CustomEditor and Entity? – Ali Sep 09 '11 at 16:19
  • posted the initBinder, part of the Controller, which is really quite simple. the rest in the Controller is Render and Action Mappings (since its Portlet-code) ..but thanks for your time. – definitely undefinable Sep 12 '11 at 10:17
  • Try to define your own as I've shown in my update. That way you can set a break-point to see what is going on. This will only work in your entity defines `myFieldName` as a `Long`, also to minimize headache, make sure it's the object and not the primitive `long`. I've looked at the source for `CustomNumberEditor` and it casts the `value` Object to `Number` where as it's probably being passed as a `String`. – Ali Sep 12 '11 at 11:12
  • alright, seems like there's no solution without an own class or at least overriding CustomNumberEditor – definitely undefinable Sep 12 '11 at 14:00
  • Depends, if you are using spring forms then there should be automatic casting to Long. What is your html like? – Ali Sep 12 '11 at 14:06
2

if someone's interested .. the code of the custom Binder that worked in the end follows..

  // prevent alphanumeric/special chars in numeric string (for backing field of type Long)
  binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true) {
     @Override
     public void setAsText(String value) {
        if (value != null && !value.isEmpty() && CustomValidator.isNumeric(value)) {
           super.setAsText(value);
        } else {
           super.setAsText(null);
        }
     }
  });

although, you still have to adjust your validation method so that it makes sense with text that was entered, got removed, and was changed to null!