Ahmet Ahmet - 4 years ago 179
Java Question

Spring MVC Controller NumberFormat Annotation Pattern Issue in BigDecimal

I have a spring controller which is taking multiple

BigDecimal
RequestParams.

My application locale is en_US but just for this controller method I need to bind and convert these
BigDecimal
parameters in de_DE locale (ie. #.###,## > DOT for grouping and COMMA for decimal separator).

These
BigDecimal
values are coming from the UI text boxes and they are already in the
de_DE
format. Here is my controller code which is failing with the following error:


"Failed to convert value of type 'java.lang.String' to required type
'java.math.BigDecimal'; nested exception is
java.lang.NumberFormatException"


@RequestMapping(value = "/create", method = RequestMethod.POST)
public ModelAndView create(@RequestParam("referenceNumber") String referenceNumber, @RequestParam("startDate") @DateTimeFormat(pattern="dd-MM-yyyy") Date startDate, @RequestParam("amount1") @NumberFormat(pattern = "#.###,##") BigDecimal amount1, @RequestParam("amount2") @NumberFormat(pattern = "#.###,##") BigDecimal amount2) {

// Do something and return

}


Spring somehow ignores my numberformat pattern. Please note that
DateTimeFormat
annotation works as expected; parsing the startDate parameter in correct form.

Any help would be appreciated.

Thanks.

Answer Source

You can use PropertyEditorSupport to handle the form input as follows:

Create class extending PropertyEditorSupport to convert String received from client to BigDecimal, for example:

import java.beans.PropertyEditorSupport;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

public class BigDecimalEditor extends PropertyEditorSupport {

    public void setAsText(String text) {
        NumberFormat formatter = NumberFormat.getNumberInstance(Locale.GERMAN);
        try {
            Number number = formatter.parse(text);
            BigDecimal bigDecimal = BigDecimal.valueOf(number.doubleValue());
            setValue(bigDecimal);
        } catch (ParseException e) {
            // handle exception here
        }
    }
}

And bind it with the controller, as:

@RestController
@RequestMapping(value = "/employee")
public class EmployeeController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(BigDecimal.class, new BigDecimalEditor());
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ModelAndView create(
            @RequestParam("amount") @NumberFormat(pattern = "#.###,##") BigDecimal amount) {
        System.out.println(amount);
        return new ModelAndView();
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download