Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the role of @InitBinder and the WebDataBinder in this case

I do some change in an existing controller that extends an abstract controller

public abstract class AbstractWizardController {


    private WizardDescriptor descriptor;


    private transient String dispacherUri;


    @InitBinder
    public void initBinder(final WebDataBinder binder) {
        final Locale locale = LocaleContextHolder.getLocale();
        final DecimalFormatSymbols decimalSymbol = new DecimalFormatSymbols(locale);
        if (Locale.FRENCH.equals(locale)) {
            decimalSymbol.setDecimalSeparator(WebConstants.Caracteres.VIRGULE);
            decimalSymbol.setGroupingSeparator(WebConstants.Caracteres.ESPACE);
        } else {
            decimalSymbol.setDecimalSeparator(WebConstants.Caracteres.POINT);
            decimalSymbol.setGroupingSeparator(WebConstants.Caracteres.VIRGULE);
        }
        final DecimalFormat decimalFormat = new DecimalFormat(PseConstants.Pattern.MONTANT_PATTERN, decimalSymbol);
        decimalFormat.setMinimumFractionDigits(NumbersEnum.DEUX.getNumber());
        // Editeur personnalisé pour les montants
        binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, decimalFormat, true));

        // Editeur personnalisé pour les dates
        final SimpleDateFormat formatDate = Locale.FRENCH.equals(locale) ? new SimpleDateFormat(WebConstants.DatesFormats.DATE_LOCAL_FRANCAIS)
                : new SimpleDateFormat(WebConstants.DatesFormats.DATE_LOCAL_ANGLAIS);
        formatDate.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(formatDate, true));
    }
 }

And this is my controller

@Controller
@RequestMapping(WebConstants.View.LETTRE_MANDAT)
public class EditerMandatController extends AbstractWizardController {

    /** Logger */
    private static final Logger LOGGER = LoggerFactory.getLogger(EditerMandatController.class);


    private transient IEditerLettreService editerLettreService;

    /**
     * Constructeur
     */
    public EditerMandatController() {
        setDispacherUri(WebConstants.View.LETTRE_MANDAT);
    }


    @RequestMapping(value = WebConstants.View.EDITER_LETTRE_MANDAT, method = RequestMethod.POST)
    public String editerLettreMandat(final HttpServletRequest req, final HttpServletResponse res,
            @ModelAttribute(WebConstants.Path.FORM) final LettreMandatBean lettreMandat, final org.springframework.ui.Model model) throws AppTechnicalException {

        final String idMandataire = WebUtilities.getIdMandataire(req);
        lettreMandat.setIdMandataire(idMandataire);

        final String lettreMandatCookie = JsonUtils.parseObjectJson(lettreMandat);

        if (StringUtils.isNotBlank(lettreMandatCookie)) {
            final Cookie cookie = new Cookie(WebConstants.Others.LETTRE_MANDAT_COOKIE + idMandataire, Base64.encodeBytes(lettreMandatCookie.getBytes()));
            cookie.setSecure(true);
            res.addCookie(cookie);
        }
        try {
            editerLettreService.editerLettre(req, res, lettreMandat);

        } catch (final AppTechnicalException e) {
            LOGGER.error(WebConstants.Messages.MESSAGE_INCIDENT_TECHNIQUE, e);
            addError(model, WebConstants.Messages.MESSAGE_INCIDENT_TECHNIQUE);
        }
        return WebConstants.View.PAGE_LETTRE_MANDAT;
    }

}

My question is what is the role of the @InitBinder and the WebDataBinder in the abstract Controller ? Thank you in advance

like image 463
e2rabi Avatar asked Jan 05 '23 23:01

e2rabi


1 Answers

WebDataBinder is used to populate form fields onto beans. An init binder method initializes WebDataBinder and registers specific handlers, etc on it.

When form fields are read on server side, it is better to read them as per their corresponding types than as strings. For example, "March 21, 2016" is better read as Java's Date type than as String. This may involve certain validations, etc. For example, a date like 03/21/2016 is probably valid in US but not in some other countries. So you can register editors, validators, etc with the DataBinder. Please take a look at: validators in InitBinder and DataBinder doc

In this case the @InitBinder method initializes the binder and registers context(locale) specific handlers, editors, etc. So when an incoming request has a date it will be handled by CustomDateEditor before it is mapped on the java bean. Or a french local currency will be handled in a different way than other locals- decimal separator.

The init binder is in abstract controller because that way other controllers can reuse the functionality and don't have to rewrite the locale specific handler.

Hope this helps.

like image 88
Atul Avatar answered Jan 08 '23 07:01

Atul