Попытка сгенерировать таблицу в формате PDF, которая будет сохранена на s3 и немедленно получена как автоматическое вложение электронной почты. - PullRequest
2 голосов
/ 17 мая 2019

В настоящее время мой код написан для создания PDF-файла, содержащего маршрут полета на локальный диск. Система автоматически отправит электронное письмо с приложенным маршрутом (который получен по тому же локальному пути). Я хочу иметь возможность хранить и извлекать эти маршруты из моего хранилища AWS S3. Мое приложение написано на Java с использованием Spring-boot / MVC / Maven. Я не могу понять это. Я только что окончил колледж с BSIT в области разработки программного обеспечения. Я действительно стремлюсь улучшить свой набор навыков, но, похоже, мне понадобится помощь в решении этого вопроса.

Уровень обслуживания-

пакет com.louis.mywebapplication.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.louis.mywebapplication.dto.ReservationRequest;
import com.louis.mywebapplication.entities.Flight;
import com.louis.mywebapplication.entities.Passenger;
import com.louis.mywebapplication.entities.Reservation;
import com.louis.mywebapplication.repos.FlightRepository;
import com.louis.mywebapplication.repos.PassengerRepository;
import com.louis.mywebapplication.repos.ReservationRepository;
import com.louis.mywebapplication.util.EmailUtil;
import com.louis.mywebapplication.util.PDFGenerator;


@Service
public class ReservationServiceImpl implements ReservationService {

    private static final Logger LOGGER =                                                 LoggerFactory.getLogger(ReservationServiceImpl.class);

    @Value("${com.louis.webapplication.itinerary.dirpath}")
    String ITINERARY_DIR;

    @Autowired
    FlightRepository flightRepository;

    @Autowired
    PassengerRepository passengerRepository;

    @Autowired
    ReservationRepository reservationRepository;

    @Autowired
    PDFGenerator pdfGenerator;

    @Autowired
    EmailUtil emailUtil;

    @Override
    public Reservation bookFlight(ReservationRequest request) {
        LOGGER.info("Inside bookFlight()");
        //Make Payment

        Long flightId = request.getFlightId();
    LOGGER.info("Fetching flight for flight id:"+flightId);
        Flight flight = flightRepository.findById(flightId).get();
        Passenger passenger = new Passenger();
        passenger.setFirstName(request.getPassengerFirstName());
        passenger.setLastName(request.getPassengerLastName());
        passenger.setPhone(request.getPassengerPhone());
        passenger.setEmail(request.getPassengerEmail());
    LOGGER.info("Saving the passenger: "+passenger);
        Passenger savedPassenger = passengerRepository.save(passenger); 
        Reservation reservation = new Reservation();
        reservation.setFlight(flight);
        reservation.setPassenger(savedPassenger);
        reservation.setCheckedIn(false);
    LOGGER.info("Saving the reservation:"+reservation);
        Reservation savedReservation reservationRepository.save(reservation);
        String filePath = ITINERARY_DIR+savedReservation.getId()+".pdf";
    LOGGER.info("Generation the ininerary");
        pdfGenerator.generateItinerary(savedReservation, filePath);
    LOGGER.info("Emailing the ininerary");
        emailUtil.sendItinerary(passenger.getEmail(), filePath);
        return savedReservation;
    }

}

Служебный слой-

package com.louis.mywebapplication.util;

import java.io.File;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

@Component
public class EmailUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmailUtil.class);

    @Autowired
    private JavaMailSender sender;

    @Value("${com.louis.mywebapplicationn.itinerary.email.subject}")
    private String EMAIL_SUBJECT;

    @Value("${com.louis.mywebapplicationn.itinerary.email.body}")
    private String EMAIL_BODY;

    public void sendItinerary(String toAddress, String filePath) {
        LOGGER.info("Inside sendItinerary()");
        MimeMessage message = sender.createMimeMessage();

        try {
            MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
            messageHelper.setTo(toAddress);
            messageHelper.setSubject(EMAIL_SUBJECT);
            messageHelper.setText(EMAIL_BODY);

            messageHelper.addAttachment("Itinerary", new File(filePath));
            sender.send(message);
        } catch (MessagingException e) {

            e.printStackTrace();
        }
    }
}

package com.louis.mywebapplication.util;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.louis.mywebapplication.entities.Reservation;

@Component
public class PDFGenerator {

    private static final Logger LOGGER = LoggerFactory.getLogger(PDFGenerator.class);
    //
    public void generateItinerary(Reservation reservation, String filePath) {
        LOGGER.info("generateItinerary()");
        Document document = new Document();

        try {
            PdfWriter.getInstance(document, new FileOutputStream(filePath));
            document.open();
            document.add(generateTable(reservation));
            document.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (DocumentException e) {

            e.printStackTrace();
        }
    }
    //
    private PdfPTable generateTable(Reservation reservation) {

        PdfPTable table = new PdfPTable(2);
        PdfPCell cell;

        cell = new PdfPCell(new Phrase("Flight Itinerary"));
        cell.setColspan(2);
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("Flight Details"));
        cell.setColspan(2);
        table.addCell(cell);

        table.addCell("Airlines");
        table.addCell(reservation.getFlight().getOperatingAirlines());

        table.addCell("Departure City");
        table.addCell(reservation.getFlight().getDepartureCity());

        table.addCell("Arrival City");
        table.addCell(reservation.getFlight().getArrivalCity());

        table.addCell("Flight Number");
        table.addCell(reservation.getFlight().getFlightNumber());

        table.addCell("Departure Date");
        table.addCell(reservation.getFlight().getDateOfDeparture().toString());

        table.addCell("Departure Time");
        table.addCell(reservation.getFlight().getEstimatedDepartureTime().toString());

        cell = new PdfPCell(new Phrase("Passengerr Details"));
        cell.setColspan(2);
        table.addCell(cell);

        table.addCell("First Name");
        table.addCell(reservation.getPassenger().getFirstName());

        table.addCell("Last Name");
        table.addCell(reservation.getPassenger().getLastName());

        table.addCell("Email");
        table.addCell(reservation.getPassenger().getEmail());

        table.addCell("Phone");
        table.addCell(reservation.getPassenger().getPhone());

        return table;
    }

}

Ответы [ 2 ]

1 голос
/ 21 мая 2019

Возможно, вы захотите взглянуть на Spring Content . Этот проект позволяет вам управлять контентом (т.е. вашими сгенерированными PDF-файлами) и связывать его с вашими объектами данных Spring. Он также обеспечивает ту же модель программирования, что и Spring Data, только для файлов и другого двоичного содержимого.

Например, если вы используете Spring Data REST (и Spring Boot), вы можете добавить обработчик событий SDR, который при создании нового резервирования (через конечную точку SDR) запускает генерацию вашего PDF, а затем использует Spring Content для хранения PFD в S3 и связывания его с резервированием.

Проект легко добавить в ваш проект следующим образом:

pom.xml

   <!-- Java API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-s3-boot-starter</artifactId>
      <version>0.8.0</version>
   </dependency>

   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest-boot-starter</artifactId>
      <version>0.8.0</version>
   </dependency>

S3Configuration.java

@Configuration
@EnableS3Stores
public class S3Configuration {
    @Bean
    public AmazonS3 client() {
        return ...your client here...
    }

}

Reservation.java

@Entity
public class Reservation {
   @Id
   @GeneratedValue
   private long id;

   ...other existing fields...

   /////////////
   //
   // Add Spring Content annotations to allow content to be associated 

   @ContentId
   private String contentId;

   @ContentLength
   private long contentLength = 0L;

   @MimeType
   private String mimeType = "";

   ...
}

ReservationPDFContentStore.java

@StoreRestResource(path="reservationPdfs")
public interface ReservationPDFContentStore extends ContentStore<Reservation, String> {
}

ReservationEventHandler.java

@RepositoryEventHandler(Reservation.class) 
public class ReservationEventHandler {

  @Autowired
  private PDFGenerator;

  @Autowired
  private ReservationPDFContentStore store;


  @HandleAfterCreate
  public void handleReservationAfterCreate(Reservation reservation){
    // generate your PDF and associate the content with your reservation
    String filePath = ...
    pdfGenerator.generateItinerary(savedReservation, filePath);
    InputStream pfdIn = new FileInputStream(filePath);
    store.setContent(reservation, pdfIn);

    // don't forget to close pdfIn!
  }
}

На высоком уровне это все, что вам нужно сделать.

Как это на самом деле работает, очень похоже на Spring Data. Когда ваше приложение запустится, Spring Content увидит зависимости spring-content-s3-boot-starter и узнает, что вы хотите хранить контент в S3. Он внедрит реализацию интерфейса ReservationPDFContentStore на основе S3, используя в качестве соединения настройку клиента @Bean в конфигурации. Он также увидит spring-content-rest-boot-starter и введет конечные точки REST, которые взаимодействуют с интерфейсом хранилища контента.

Так, например:

curl -X POST /reservations/ (с соответствующим приложением / hal + json payload)

создаст новое резервирование в вашей системе и вызовет обработчик событий, который сгенерирует PDF-файл, сохранит его на S3 и свяжет с вновь созданным резервированием.

curl /reservationPdfs/{reservationId}

будет загружать PDF, когда вам это нужно.

Преимущество Spring Data и Content заключается в том, что кроме генератора PDF вам не нужно писать стандартный контроллер или служебный код. Учитывая пару интерфейсов (расширение CrudRepository и ContentStore), Spring может внедрить все это для вас.

Вы можете найти больше примеров Spring Content здесь .

НТН

0 голосов
/ 19 мая 2019

Ваше решение в основном подходит для генерации файлов и отправки по электронной почте.Я бы порекомендовал записать файлы во временную папку (в / usr / local, если это в Linux, в папке Users / your user, если windows), а затем удалите файл после того, как он будет отправлен по электронной почте.Единственная причина хранить их на s3 будет в том случае, если вам понадобится получить их позже через ваше приложение.Если это так, то лучший способ сделать это - создать таблицу в вашей базе данных для хранения метаданных, которые вы будете использовать для поиска файла, таких как (идентификатор пользователя, имя файла, дата, сегмент s3, s3key, ...).Затем можно использовать Java-API s3 для записи файла в s3 (до удаления его из tmp).Примеры s3 java API можно найти здесь: https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-s3.html.
вот базовый пример размещения файла на s3:

 AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
 AmazonS3 s3client = AmazonS3ClientBuilder
        .standard()
        .withCredentials(new AWSStaticCredentialsProvider(credentials))
        .withRegion(Regions.US_EAST_2)
        .build();
s3client.putObject(bucket, key, file);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...