java - 尝试生成一个 pdf 表,该表将存储在 s3 上并立即作为自动电子邮件附件检索

标签 java spring-mvc amazon-s3 itext aws-sdk

目前,我编写的代码生成一个 pdf 文件,其中包含到本地驱动器的航类行程。系统将自动发送一封附有行程的电子邮件(从同一本地路径检索)。我希望能够从我的 AWS S3 存储桶中存储和检索这些行程。我的应用程序是使用 Spring-boot/MVC/Maven 用 Ja​​va 编写的。我似乎无法弄清楚这一点。我刚从大学毕业,获得了软件开发的 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;
    }

}

最佳答案

您可能想看看 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 中。它将注入(inject) ReservationPDFContentStore 接口(interface)的基于 S3 的实现,使用配置中的客户端 @Bean 设置作为其连接。它还将看到 spring-content-rest-boot-starter 并将注入(inject)与内容存储接口(interface)对话的 REST 端点。

所以,例如:

curl -X POST/reservations/ (具有适当的 application/hal+json 负载)

将在您的系统中创建一个新的预订并触发将生成 PDF 的事件处理程序,将其存储在 S3 中并将其与新创建的预订相关联。

curl/reservationPdfs/{reservationId}

将在您需要时获取 PDF。

Spring Data 和 Content 的优势在于,除了 PDF 生成器之外,您无需编写任何样板 Controller 或服务代码。给定几个接口(interface)(扩展 CrudRepositoryContentStore)Spring 能够为您注入(inject)所有内容。

您可以找到更多 Spring Content 示例 here .

HTH

关于java - 尝试生成一个 pdf 表,该表将存储在 s3 上并立即作为自动电子邮件附件检索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56192267/

相关文章:

java - 外部 jar 文件破坏了 gwt/glassfish 编译

java - 像使用同步关键字时一样,在 CyclicBarrier 或 CountDownLatch 上进行缓存刷新

java - 文件保存到公共(public)存储目录的问题

java - 将 GUI 添加到现有的基于 Java 控制台的程序

java - 使用XML数据时出错内容类型 'application/xml;charset=utf-8' spring不支持

java - 如何合并这两个 Spring Boot Controller ?

javascript - 如何在 Javascript/ES6 的 Aurelia 浏览器应用程序中使用 AWS S3?

java - 如何在spring 3.0中注入(inject)map类型对象

amazon-web-services - API 网关的 S3 重定向规则不起作用

amazon-s3 - 谷歌云存储aws迁移,如何获取访问/秘钥?