En la publicación anterior vimos cómo crear conversores personalizados para propiedades dentro de una clase anotada con @RequestBody
.
En esta ocasión veremos cómo hacer la misma lógica para parámetros anotados como @RequestParam
.
Refactorizando el ejemplo de la publicación anterior, supongamos que tenemos el siguiente controlador:
@RestController
@AllArgsConstructor
@RequestMapping("transactions")
public class CreateTransactionController {
@PostMapping
public ResponseEntity<CreateTransactionOutputDto> createTransaction(
@RequestParam Double amount,
) {
//
}
}
Y enviamos una petición a este endpoint con los siguientes parámetros:
POST '{{apiUrl}}/transactions?amount=45.13'
Por defecto Spring será capaz de enlazar cada elemento de la petición con su correspondiente parámetro de nuestro controlador, siempre y cuando encuentre el conversor adecuado para ello.
No tendremos problemas si declaramos parámetros de tipo primitivo o sus wrappers, pero en caso de querer enlazarlos a una clase, debemos crear un conversor.
Cómo mapear Value Objects
Supongamos ahora que actualizamos el tipo de clase del parámetro de la siguiente manera:
// file: Money
public record Money(Double value) {...} // <- Creamos un record para encapsular un elemento de tipo Money
// file: CreateTransactionController
@PostMapping
public ResponseEntity<CreateTransactionOutputDto> createTransaction(
@RequestParam Money amount, // <- Actualizamos el tipo parámetro
) {
//
}
Para que Spring sea capaz de convertir estos datos correctamente, creamos el conversor extendiendo de org.springframework.core.convert.converter.Converter
:
import org.springframework.core.convert.converter.Converter;
public class MoneyConverter implements Converter<String, Money> { // <- Implementamos la interfaz Converter
@Override
public Money convert(String source) {
return new Money(Double.parseDouble(source)); // <- Implementamos la conversión con la lógica que deseemos
}
}
Una vez más, se trata de un código muy simple. Únicamente es necesario implementar la infertaz Converter
indicando como tipo de parámetros la clase de entrada y la de salida, en este caso indicamos que se va a convertir una String
en la clase Money
.
Por último, debemos indicar a Spring que se utilice este conversor para mapear las instancias de la clase Money
, incluyendo el nuevo conversor dentro del registro de formateadores:
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new MoneyConverter()); // <- Instanciamos e incluimos nuestro conversor
}
}
Una vez hecho esto, Spring será capaz de utilizar nuestro conversor cuando intente mapear propiedades de tipos distintos a los primitivos/wrappers o las clases para las que ya cuenta con conversores.
Top comments (0)