Setting locale in JSP or JVM does not format numbers correctly

Refresh

April 2019

Views

197 time

1

Intro

I have a JSP page that displays numbers from objects using the notation:

${grant.project.cost}

They are displayed in United States notation where decimal = "." but I want the european notation.

I have tried to set the locale using the following methods:

  1. setting the locale within JSP using <fmt:setLocale value="${myLocale}" scope="page" />
  2. setting the locale from controller using: Locale.setDefault(new Locale("el", "GR"));
  3. setting the local from jvm parameter using: -Duser.language=el-GR

Unfortunately numbers continue to be outputted in American notation. I'd prefer to do it via the regional settings so that editing/reparsing Strings won't require having to convert notations.

Update

I added the following code and see that the the country/language have changed but the values in ${} continue to be in American notation.

<c:out value="${pageContext.request.locale.language}"/>

Update2

According to the following link, setting the custom locale should affect double value output but does not do so: https://stackoverflow.com/a/5038805/1688441

I also tried this in the controller but I am also getting american notation in the console:

    Locale.setDefault(new Locale("el", "GR"));
    System.out.println("test:"+new Double("1.2345"));

Output:

test: 1.2345

Related

1 answers

1

Intro

Since I was using Spring MVC controller I ended up doing the following. Because it's a bit twisted I outline the steps.

  • Add your attributes to the model of the edit controller
  • Add an InitBinding method
  • Add your modelAttribute to the save controller method.

Edit Controller

In my edit method method (RequestMapping) I added the entities that contain Double values and that I would like them to be formatted as differently:

    model.addAttribute("grant", grant);

Binding

Following I added the following Binder that is executed for every Attibute object of the model:

@InitBinder("grant")
    public void registrarInitBinder(HttpServletRequest request, ServletRequestDataBinder binder) { // register or save
        NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
        DecimalFormat df = (DecimalFormat)nf;
        df.setMinimumFractionDigits(2);
        binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class,df, true));
    }

This correctly took care of my Double objects contained in grant and project. I have the impression though that only parameters mapped with path= actually work and are formatted correctly.

Save Method

In my Save method (requestMapping) I include the grant

@RequestMapping(value = "/selection/save", method = RequestMethod.POST)
public String selectionSave(
        Model model,
        @RequestParam(value = "type", required = false) String type,
        @Valid @ModelAttribute(value = "grant") GrantEntity grant,
        BindingResult bindingResult,
        HttpServletRequest request) throws ParseException 

Conclusion

Using these steps your Objects will be formatted and displayed correctly, and also parsed correctly when Edited.

Unfortunately for objects located in more complex structures (Objects within Object, e.g. Lists, or Maps), I ended up using the HttpServletRequest request object and extracting them from the request. This is because only the actual Double Fields of my Object were formatted but not the Double fields of Objects within the Object or Objects within Maps of the Object.

For both viewing/editing and saving I created custom methods that use a NumberFormatter.

Viewing:

 public static Double parseFormattedDouble(String value) throws ParseException {
        nfStatic.setMinimumFractionDigits(2);
        return nfStatic.parse(value).doubleValue();
    }

Parsing after POST Request (Save):

updateFundB = request.getParameter("FundB4");
Double fundB4 = FormattedDoubleAmount.parseFormattedDouble(updateFundB != null && !updateFundB.equals("") ? updateFundB : "0");
saveEntity.updateFundB4(fundB4);

I would have prefered to use the binding method for everything but my experiments with Collections didn't work.

References