[[webflux-ann-initbinder]]
= `DataBinder`

[.small]#xref:web/webmvc/mvc-controller/ann-initbinder.adoc[See equivalent in the Servlet stack]#

`@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods, to
initialize instances of `WebDataBinder`. Those, in turn, are used to:

* Bind request parameters (that is, form data or query) to a model object.
* Convert `String`-based request values (such as request parameters, path variables,
headers, cookies, and others) to the target type of controller method arguments.
* Format model object values as `String` values when rendering HTML forms.

`@InitBinder` methods can register controller-specific `java.beans.PropertyEditor` or
Spring `Converter` and `Formatter` components. In addition, you can use the
xref:web/webflux/config.adoc#webflux-config-conversion[WebFlux Java configuration] to register `Converter` and
`Formatter` types in a globally shared `FormattingConversionService`.

`@InitBinder` methods support many of the same arguments that `@RequestMapping` methods
do, except for `@ModelAttribute` (command object) arguments. Typically, they are declared
with a `WebDataBinder` argument, for registrations, and a `void` return value.
The following example uses the `@InitBinder` annotation:

--
[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	@Controller
	public class FormController {

		@InitBinder // <1>
		public void initBinder(WebDataBinder binder) {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			dateFormat.setLenient(false);
			binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
		}

		// ...
	}
----
<1> Using the `@InitBinder` annotation.

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	@Controller
	class FormController {

		@InitBinder // <1>
		fun initBinder(binder: WebDataBinder) {
			val dateFormat = SimpleDateFormat("yyyy-MM-dd")
			dateFormat.isLenient = false
			binder.registerCustomEditor(Date::class.java, CustomDateEditor(dateFormat, false))
		}

		// ...
	}
----
<1> Using the `@InitBinder` annotation.
======
--

Alternatively, when using a `Formatter`-based setup through a shared
`FormattingConversionService`, you could re-use the same approach and register
controller-specific `Formatter` instances, as the following example shows:

--
[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	@Controller
	public class FormController {

		@InitBinder
		protected void initBinder(WebDataBinder binder) {
			binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); <1>
		}

		// ...
	}
----
<1> Adding a custom formatter (a `DateFormatter`, in this case).

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	@Controller
	class FormController {

		@InitBinder
		fun initBinder(binder: WebDataBinder) {
			binder.addCustomFormatter(DateFormatter("yyyy-MM-dd")) // <1>
		}

		// ...
	}
----
<1> Adding a custom formatter (a `DateFormatter`, in this case).
======
--


[[webflux-ann-initbinder-model-design]]
== Model Design
[.small]#xref:web/webmvc/mvc-controller/ann-initbinder.adoc#mvc-ann-initbinder-model-design[See equivalent in the Servlet stack]#


