2

J'ai un contrôleur de ressort qui prend plusieurs BigDecimal RequestParams. Mes paramètres régionaux d'application sont en_US mais pour cette méthode de contrôleur, j'ai besoin de lier et de convertir ces paramètres BigDecimal dans les paramètres régionaux de_DE (par exemple, # ###, ##> DOT pour le regroupement et COMMA pour le séparateur décimal). Ces valeurs BigDecimal proviennent des zones de texte de l'interface utilisateur et sont déjà au format de_DE. Voici mon code de contrôleur qui échoue avec l'erreur suivante:Printemps MVC Controller NumberFormat Modèle d'annotation Problème en BigDecimal

"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 ne tient pas compte en quelque sorte mon modèle numberformat. Veuillez noter que l'annotation DateTimeFormat fonctionne comme prévu. l'analyse du paramètre startDate sous forme correcte.

Toute aide serait appréciée.

Merci.

+0

Vous pouvez déboguer une partie javascript de votre code. Je suppose que vous envoyez une valeur de chaîne. Vous pouvez le convertir en numéro dans votre code javascript –

+0

@ user3087839 javascript n'est pas pertinent ici; Bien sûr, j'envoie un tas de ficelles du côté de la vue. L'envoi d'un formulaire permet d'envoyer des paires de valeurs de clé de chaîne d'un côté à l'autre. Je demande comment convertir ces valeurs de paramètre de chaîne d'une manière personnalisée. – Ahmet

+0

L'annotation fonctionne car elle génère une erreur comme NumberFormatException. C'est bizarre d'envoyer une chaîne et d'essayer de la formater plus tard. –

Répondre

2

Vous pouvez utiliser PropertyEditorSupport pour gérer l'entrée de formulaire comme suit:

Créer une classe extension PropertyEditorSupport pour convertir chaîne reçue du client à BigDecimal, par exemple:

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 
     } 
    } 
} 

et le lier avec le contrôleur, comme:

@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(); 
    } 
} 
+0

Merci pour la réponse. C'est une solution de contournement, car avec customEditors, nous n'avons pas besoin d'utiliser l'annotation NumberFormat. J'aimerais vraiment savoir s'il est possible d'utiliser l'annotation NumberFormat avec un motif personnalisé, tout comme le motif DateTimeFormat. – Ahmet

+1

+1 C'est la meilleure méthode pour moi, mais vous pouvez enregistrer un classeur d'initialisation global pour ne pas avoir à en enregistrer un pour chaque contrôleur (http://keenformatics.blogspot.it/2013/08/how-to- create-global-initbinder-in-spring.html). Et vous n'avez pas besoin d'utiliser l'annotation 'NumberFormat' dans le paramètre du contrôleur,' CustomEditor' convertira également le montant sans l'annotation. – amicoderozer

1

Je résolu mon problème avec: @RequestParam(value="amount1", required=false) @NumberFormat(pattern="#0,00") BigDecimal amount1

+0

J'ai appliqué une solution de contournement avec PropertyEditorSupport mais je vais l'essayer et vous le faire savoir. Merci – Ahmet

+0

effectivement ce que vous avez suggéré fonctionne également. Je l'ai essayé hier et ça marche bien. – Ahmet