Метод публикации с использованием DTO

Я хочу использовать DTO для связи с Angular, но на самом деле это не работает. Я хочу создать запрос POST для добавления данных из моего приложения в базу данных с использованием модели Dto.

Мои ошибки вы можете увидеть на картинке: Метод публикации с использованием DTO

Метод публикации с использованием DTO

Мой класс Заказчик:

@Entity
@Table(name = "customer")
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@Column(name = "name")
private String name;

@OneToMany
private List<Ticket> ticket;
...

Класс CustomerDto:

public class CustomerDto {
private String name;
private List<TicketDto> ticket;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<TicketDto> getTicket() {
    return ticket;
}

public void setTicket(List<TicketDto> ticket) {
    this.ticket = ticket;
}
}

Класс CustomerController:

@Autowired
CustomerService customerService;

@PostMapping(value = "/customers/create")
public Customer postCustomer(@RequestBody CustomerDto customerDto, List<TicketDto> ticketDtos) {
    //ArrayList<TicketDto> tickets = new ArrayList<>();
    ticketDtos.add(customerDto.getName());
    ticketDtos.add(customerDto.getTicket());
    Customer _customer = customerService.save(new Customer(customerDto.getName(), ticketDtos ));
    return _customer;
}

Обслуживание клиентов:

public interface CustomerService {

void save(CustomerDto customerDto, List<TicketDto> ticketDtos);
}

CustomerServiceImpl:

@Service
public class CustomerServiceImpl implements CustomerService {

@Autowired
CustomerRepository repository;

@Override
public void save(CustomerDto customerDto, List<TicketDto> ticketDtos) {
    Customer customer = new Customer();
    customer.setName(customerDto.getName());
    customer.setTicket(customerDto.getTicket());

    List<Ticket> tickets = new ArrayList<>();
    for (TicketDto ticketDto : ticketDtos) {
        Ticket ticket = new Ticket();
        ticket.setDestinationCity(ticketDto.getDepartureCity());
        ticket.setDestinationCity(ticketDto.getDestinationCity());
        tickets.add(ticket);
    }
}

вы пытаетесь добавить значение String в List <TicketDto> ticketDtos, и вы пытаетесь использовать конструктор Customer с этим списком, но он ожидает List <Ticket>

vlad324 01.12.2018 20:39

@ vlad324 спасибо, так как я могу сохранить Customer со списком tickets?

Viola 01.12.2018 20:47

@Viola, ваш метод сохранения обслуживания клиентов принимает CustomerDto customerDto, List <TicketDto> ticketDtos, и вы пытаетесь передать Customer

Chirdeep Tomar 01.12.2018 21:03

@Viola, вы можете создать список билетов из TicketDTO и добавить этот список клиенту!

Yogen Rai 01.12.2018 21:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
1 299
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку ваш CustomerServiceImpl принимает CustomerDto и список TicketDtos, вам необходимо изменить вызов метода на контроллере, как показано ниже:

Класс CustomerController:

@Autowired
CustomerService customerService;

@PostMapping(value = "/customers/create")
public Customer postCustomer(@RequestBody CustomerDto customerDto) {
    Customer _customer = customerService.save(customerDto));
    return _customer;
}

И обновите CustomerServiceImpl как:

@Service
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    CustomerRepository repository;

    // change save to return saved customer
    @Override
    public Customer save(CustomerDto customerDto) {
        Customer customer = new Customer();
        customer.setName(customerDto.getName());
        // customer.setTicket(customerDto.getTicket()); // remove this

        List<Ticket> tickets = new ArrayList<>();
        for (TicketDto ticketDto : customerDto.getTicketDtos) {
            Ticket ticket = new Ticket();
            ticket.setDestinationCity(ticketDto.getDepartureCity());
            ticket.setDestinationCity(ticketDto.getDestinationCity());
            tickets.add(ticket);
        }
        customer.setTickets(tickets); // add this to set tickets on customer
        return repository.save(customer);
    }

Очевидно, вам также нужно изменить свой интерфейс:

public interface CustomerService {

     Customer save(CustomerDto customerDto);
}

спасибо, но это все еще не работает, что мне нужно изменить в моей части Angular, чтобы объединить модель Dto с моим интерфейсом? Erlier я использую только класс Customer.

Viola 01.12.2018 21:42

Вы не можете передать два аргумента в контроллер. Избавьтесь от List <TicketDto> ticketDtos из метода postCustomer и создайте тело из angular как DTO

Chirdeep Tomar 01.12.2018 21:46

@ChirdeepTomar огромное спасибо, чувак! Я действительно потерял там рассудок! :)

Yogen Rai 01.12.2018 22:08

@Viola, пожалуйста, посмотрите на это еще раз, я обновил ответ! до тех пор, пока вы не передадите правильный dto из углового приложения, все должно быть в порядке! если не можете разобраться, отправьте мне тело запроса!

Yogen Rai 01.12.2018 22:09

@YogenRai работает, только если я прокомментировал часть с List<Ticket> tickets в CustomerServiceImpl. Таким образом, сохраняется только name, потому что сохранение List<Ticket> у меня не работает. Вот мой новый вопрос по Angular: stackoverflow.com/questions/53575487/…

Viola 01.12.2018 23:13

@Viola вы запрашиваете неверное тело !! На вашем теле должно быть имя пользователя и список ticketDtos!

Yogen Rai 01.12.2018 23:16

@YogenRai, пожалуйста, ответьте на мой новый вопрос? заранее спасибо :)

Viola 01.12.2018 23:20

Для преобразования сущности в DTO нам нужно использовать библиотеку ModelMapper или mapstruct. С помощью этих библиотек мы можем легко преобразовать Dto в entity и entity в dto объект. После добавления любой зависимости мы можем ее использовать.

Как мы можем использовать, Посмотрим ...

Определите bean-компонент modelMapper в конфигурации Spring.

@Bean
public ModelMapper modelMapper() {
    return new ModelMapper();
}

Предположим, нам нужно преобразовать List в List obj, тогда мы можем сделать это просто так:

List<TicketDto> ticketDtos = .... //Suppose It is holding some data
List<Ticket> tickets = ticketDtos.stream()
                       .map(tkt-> mappper.map(tkt, ticket.class))
                       .collect(Collectors.toList());

Очень просто использовать как mappper.map (targetClass, DestinationClass.class) Я использовал здесь код Java8, но вы можете использовать кого угодно. Я надеюсь, что это будет вам очень полезно.

Другие вопросы по теме