- Crear una interfaz básica de MapStruct que permita mapear de un objeto
Cliente
a un objetoClienteDto
y viceversa. - Decorar las clases anteriores con las anotaciones de Lombok para autogenerar sus métodos setter, getter, constructores, etc.
- Hacer que Spring inyecte de forma automática el objeto Mapper creado por MapStruct en los controladores usando las anotaciones de Lombok.
- Tener instalado el IDE IntelliJ Idea Community Edition con el plugin de Lombok activado.
- Tener instalada la última versión del JDK 11 o 17.
-
Entra al sitio de Spring Initializr. Ahí verás una sola página dividida en dos secciones. Comienza llenando la información de la sección del lado izquierdo. Selecciona:
-
En la ventana que se abre selecciona las siguientes opciones:
- Grupo, artefacto y nombre del proyecto.
- Tipo de proyecto: Maven Project.
- Lenguaje: Java.
- Forma de empaquetar la aplicación: jar.
- Versión de Java: 11 o 17.
-
En la sección de la derecha (las dependencias) presiona el botón
Add dependencies
y en la ventana que se abre busca las dependenciasSpring Web
yLombok
. -
Dale un nombre y una ubicación al proyecto y presiona el botón Generate.
-
En el proyecto que se acaba de crear debes tener el siguiente paquete
org.bedu.java.backend.sesion5.ejemplo3
. Dentro crea los subpaquetes:model
,dtos
ycontrollers
. Dentro del paquetedtos
crea un subpaquetemappings
. -
Agrega al proyecto, en el archivo pom.xml las dependencias de MapStruct (las de Lombok se agregaron al momento de crear el proyecto):
<properties> <java.version>11</java.version> <org.mapstruct.version>1.4.1.Final</org.mapstruct.version> </properties> <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> <optional>true</optional> </dependency> </dependencies>
-
Agrega el plugin de Maven para MapStruct, el cual se encargará de generar el código para realizar el mapeo correspondiente.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.1.0</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
-
Dentro del paquete
model
crea una clase llamadaCliente
con los siguientes atributos:private long id; private String nombre; private String correoContacto; private int numeroEmpleados; private String direccion;
-
Decora esta clase con las anotaciones
@Data
y@Builder
de Lombok:@Data @Builder public class Cliente { private long id; private String nombre; private String correoContacto; private int numeroEmpleados; private String direccion; }
-
Dentro del paquete
dtos
agrega una clase llamadaClienteDto
con los siguientes atributos. También anota esta clase con@Data
y@Builder
:@Data @Builder public class ClienteDto { private String nombre; private String numeroEmpleados; private String direccion; }
-
Dentro del paquete
mappings
crea una interface llamadaClienteMapper
y decórala con la anotación@Mapper
:@Mapper public interface ClienteMapper { }
-
En la anotación
@Mapper
agrega el atributocomponentModel
con el valor despring
. Esto le indica a MapStruct que debe marcar la clase generada para que pueda funcionar como un componente de Spring.@Mapper(componentModel = "spring") public interface ClienteMapper { }
-
Agrega los siguientes métodos dentro de la interface
ClienteMapper
, el primero le dice a MapStruct que debe crear un método que transforme de unClienteDto
(que recibe como parámetro) a unCliente
(que es el objeto que el método regresará). El segundo método hace lo opuesto, recibe un objetoCliente
y regresa un objetoClienteDto
con los atribtos mapeados provenientes delCliente
. MapStruct se encargará de crear una implementación de esta interface.Cliente clienteDtoToCliente(ClienteDto clienteDto); ClienteDto clienteToClienteDto(Cliente cliente);
La interface completa debe verse de esta forma:
@Mapper(componentModel = "spring") public interface ClienteMapper { Cliente clienteDtoToCliente(ClienteDto clienteDto); ClienteDto clienteToClienteDto(Cliente cliente); }
-
En el paquete
controllers
agrega una clase llamadaClienteController
y decórala con la anotación@RestController
:@RestController @RequestMapping("/cliente") public class ClienteController { }
-
Agrega un nuevo manejador de peticiones POST que reciba un identificador como parámetro Un objeto de tipo
Cliente
:@PostMapping public ResponseEntity<Void> creaCliente(@RequestBody Cliente cliente){ return ResponseEntity.created(URI.create("1")).build(); }
-
Declara una instancia de tipo
ClienteMapper
en el controlador y úsala dentro del métodocreaCliente
para obtener un objeto de tipoClienteDto
con los valores del objetoCliente
recibido e imprime sus valores en consola:@RestController @RequestMapping("/cliente") public class ClienteController { private final ClienteMapper mapper; @PostMapping public ResponseEntity<Void> creaCliente(@RequestBody Cliente cliente){ ClienteDto clienteDto = mapper.clienteToClienteDto(cliente); System.out.println(clienteDto); return ResponseEntity.created(URI.create("1")).build(); } }
-
Agrega al nivel de la clase la anotación
@RequiredArgsConstructor
de Lombok para crear un constructor que reciba los atributos marcados comofinal
, en este caso el el objetoClienteMapper
. Al final la clase debe quedar de esta forma:@RestController @RequestMapping("/cliente") @RequiredArgsConstructor public class ClienteController { private final ClienteMapper mapper; @PostMapping public ResponseEntity<Void> creaCliente(@RequestBody Cliente cliente){ ClienteDto clienteDto = mapper.clienteToClienteDto(cliente); System.out.println(clienteDto); return ResponseEntity.created(URI.create("1")).build(); } }
-
Ejecuta la aplicación y envía el siguiente objeto JSon desde Postman:
{ "nombre": "BeduORG", "correoContacto": "[email protected]", "numeroEmpleados": "20", "direccion": "direccion" }
-
Debes recibir la siguiente respuesta en Postman:
y debes tener el siguiente mensaje en la consola de IntelliJ: