Замена сущности JPA на DTO

Вы когда-нибудь сталкивались с проблемой уязвимости Sonar, такой как:

Replace this persistence entity with a POJO or DTO object.

Это происходит, когда вы передаете в @ResponseBody вызова REST сущность персистентности, а не объект DTO.

В этой статье мы расскажем вам, как можно заменить сущность персистентности на объект DTO.

Некоторое время назад я написал статью о том, как создать Spring Boot Rest API.

Вы можете клонировать репозиторий Github по этой ссылке.

Мы будем использовать это приложение в качестве эталона.

Давайте начнем.

#1. ДОБАВЬТЕ ОТОБРАЖАТЕЛЬ МОДЕЛЕЙ

Model Mapper — это библиотека отображения объектов. Она позволяет легко преобразовать одну объектную модель в другую объектную модель.

В pom.xml добавьте зависимость Model Mapper:

 <dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>2.4.5</version>
</dependency>
Войти в полноэкранный режим Выйти из полноэкранного режима

P.S.: если у вас возникнут проблемы после добавления вышеуказанной зависимости, обычно помогает выполнение команды mvn clean install.

#2. СОЗДАНИЕ ОБЪЕКТА ПЕРЕДАЧИ ДАННЫХ

Мартин Фаулер представил паттерн Data Transfer Object в своей книге «Patterns of Enterprise Application Architecture».

Объект передачи данных — это объект, который переносит данные между процессами.

Этот объект не содержит никакой бизнес-логики.

В каталоге src/main/java/com/techwithmaddy/CustomerAPI:

  1. Создайте новый пакет под названием dto (все строчные буквы).
  2. Создайте класс CustomerDTO в пакете dto.

Этот класс имеет следующее содержание:

package com.techwithmaddy.CustomerAPI.dto;

import lombok.Data;

@Data
public class CustomerDTO {

    private String firstName;
    private String lastName;
    private String email;
    private String phoneNumber;

}
Вход в полноэкранный режим Выход из полноэкранного режима

#2. СОЗДАНИЕ КЛАССА-КОНВЕРТЕРА КЛИЕНТА

Этот класс-конвертер отвечает за преобразование сущности в DTO и наоборот.

В директории src/main/java/com/techwithmaddy/CustomerAPI:

  1. Создайте еще один пакет под названием converter (все строчные буквы).
  2. Создайте класс CustomerConverter в пакете converter.

Этот класс имеет следующее содержание:

package com.techwithmaddy.CustomerAPI.converter;

import com.techwithmaddy.CustomerAPI.dto.CustomerDTO;
import com.techwithmaddy.CustomerAPI.model.Customer;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;

@Component
public class CustomerConverter {

    public CustomerDTO convertEntityToDto(Customer customer) {
        ModelMapper modelMapper = new ModelMapper();
        CustomerDTO customerDTO = modelMapper.map(customer, CustomerDTO.class);
        return customerDTO;
    }

    public Customer convertDtoToEntity(CustomerDTO customerDTO) {
        ModelMapper modelMapper = new ModelMapper();
        Customer customer = modelMapper.map(customerDTO, Customer.class);
        return customer;
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

#3. РЕФАКТОРИНГ КЛАССА ОБСЛУЖИВАНИЯ КЛИЕНТОВ

Мы хотим использовать CustomerDTO вместо объекта базы данных сущности Customer.

Мы можем рефакторить этот класс, импортировав ModelMapper и CustomerConverter и автоматически соединив их.

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    CustomerConverter customerConverter;
Вход в полноэкранный режим Выход из полноэкранного режима

Метод saveCustomer() теперь будет выглядеть следующим образом:

    public CustomerDTO saveCustomer(CustomerDTO customerDTO) {
        Customer customer = customerConverter.convertDtoToEntity(customerDTO);
        customer = customerRepository.save(customer);
        return customerConverter.convertEntityToDto(customer);
    }
Вход в полноэкранный режим Выход из полноэкранного режима

#4. РЕФАКТОРИНГ КЛАССА КОНТРОЛЛЕРА КЛИЕНТА

Добавьте это свойство в контроллер Rest:

    @Autowired
    private CustomerConverter customerConverter;
Войти в полноэкранный режим Выйти из полноэкранного режима

И отрефакторить этот метод saveCustomer, чтобы использовать CustomerDTO, а не класс Entity:

    @RequestMapping(method = {POST}, path = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
    public CustomerDTO saveCustomer(@Valid @RequestBody CustomerDTO customerDTO){
        return customerService.saveCustomer(customerDTO);
    }
Войти в полноэкранный режим Выйти из полноэкранного режима

#5. ЗАПУСК ПРИЛОЖЕНИЯ

В рамках данного руководства мы хотим проверить, работают ли вышеуказанные изменения.

Поэтому временно закомментируйте:

  1. Запросы GET, PUT и PATCH в Rest Controller.
  2. Весь класс CustomerServiceTest.

Теперь вы можете запустить приложение.

  • На Postman создайте следующий POST-запрос и нажмите кнопку SEND:

  • В MySQL вы должны увидеть нового клиента, добавленного в таблицу.

#6. ЗАЧЕМ ИСПОЛЬЗОВАТЬ DTO ВМЕСТО СУЩНОСТИ?

Давайте представим следующий сценарий:

> Школа хочет сохранить данные о своих учениках. Существует база данных, в которой хранятся имена, фамилии, электронная почта и другая конфиденциальная информация об учениках. Учителя имеют доступ только к некоторым данным, хранящимся в базе данных (таким как имя, фамилия и электронная почта). Остальная информация не будет доступна и видна учителям. Учителя могут видеть только те данные, которые им нужны.

Объекты передачи данных работают именно так: они хранят часть данных, имеющихся в базе данных, без бизнес-логики.

В архитектуре Spring Boot клиент взаимодействует с уровнем контроллера.

Если бы у нас не было Data Transfer Objects, нам пришлось бы использовать класс Entity в классе контроллера, что создало бы риск уязвимости в нашем приложении.

ЗАКЛЮЧЕНИЕ

В этой статье мы показали вам, как преобразовать сущность в DTO и как использовать DTO в ResponseBody REST-вызова.

Я надеюсь, что вы нашли эту статью полезной.

Знаете ли вы какой-либо другой подход? Пожалуйста, сообщите мне об этом в комментариях.

До следующего раза! 🙋🏾♀️

ДОПОЛНИТЕЛЬНЫЕ РЕСУРСЫ

  • StackExchange: Как использовать DTO вместо Entity?

  • Виктория Сенуич, Stack Abuse: Data Transfer Object Pattern в Java — реализация и отображение

  • Baeldung: Паттерн DTO (объект передачи данных)

Оцените статью
Procodings.ru
Добавить комментарий