dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation('com.sendgrid:sendgrid-java:4.6.1')
}
SendGrid Attachments with Spring Boot
Upasana | August 23, 2020 | 3 min read | 0 views
SendGrid allows us to attach files with email using base64 encoded format and, it also provides a helper method to seamlessly create emails with attachment.
Gradle setup
You can always head to https://start.spring.io/ for creating a Spring Boot starter project.
Creating attachment payload
In this article we will use SendGrid helper class (Attachments
) for attaching content of an file with email.
package com.sendgrid.helpers.mail.objects;
@Component
public class SendGridClient {
@Autowired
private SendGrid sendGrid;
void sendCustomEmail() throws IOException {
Email from = new Email("donotreply@example.org", "Example Org.");
String subject = "Sending attachment emails with SendGrid is Fun";
Email to = new Email("foo@example.org");
Content content = new Content("text/plain", "and easy to do anywhere, even with Java");
Mail mail = new Mail(from, subject, to, content);
addAttachment(mail);
sendInternal(mail);
}
void addAttachment(Mail mail) throws IOException {
try (final InputStream inputStream = Files.newInputStream(Paths.get("/path/to/foo.pdf"))) {
final Attachments attachments = new Attachments
.Builder("foo.pdf", inputStream) (1)
.withType("application/pdf")
.build();
mail.addAttachments(attachments);
}
}
void sendInternal(Mail mail) throws IOException {
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sendGrid.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
if (response.getStatusCode() >= 200 && response.getStatusCode() <= 299) {
System.out.println("Successfully sent email with status code: " + response.getStatusCode());
}
} catch (IOException ex) {
System.out.println("Error sending email" + ex.getMessage());
throw ex;
}
}
}
1 | SendGrid does not close the stream, so we must take care of closing it by our own. try-with-resource will take care of this in our case. |
Kotlin equivalent is:
fun addAttachment(mail: Mail, filePath: String = "/path/to/foo.pdf", name: String = "foo.pdf", contentType: String = "application/pdf") {
Files.newInputStream(Paths.get(filePath)).use {
val attachments: Attachments = Attachments.Builder(name, it)
.withType(contentType)
.build()
mail.addAttachments(attachments)
}
}
Optionally, we can develop our own function for converting a file attachment to base64 format using standard java library, as shown below:
-
read file into byte array
-
convert bytes to base64 format using Java 8
java.util.Base64
import java.util;
import java.io.InputStream;
import java.nio.file.Files;
public class Utility {
private String convertFileToBase64(Path pathToFile) {
int read = 0;
byte[] bytes = new byte[4096];
try(InputStream content = Files.newInputStream(pathToFile)) {
while ((read = content.read(bytes)) != -1) {
baos.write(bytes, 0, read);
}
return Base64.getEncoder().encodeToString(baos.toByteArray());
} catch (IOException e) {
throw new RuntimeException("Unable to convert content stream to base 64 encoded string", e);
}
}
}
You can even read the entire file into memory and convert it into Base64 format using below code:
private String convertFileToBase64(File file) {
return Base64.getEncoder().encodeToString(Files.toByteArray(file));
}
private void send() {
Mail mail = new Mail(from, subject, to, content);
Attachments attachment = new Attachments();
attachment.setContent(convertFileToBase64(new File("foo.pdf")));
attachment.setFilename("foo.pdf");
attachment.setType("application/pdf");
mail.addAttachments(attachment);
//Rest of the email stuff
}
Optionally, on unix systems you can use command line utility to manually convert a file into base64 and vice versa.
$ echo 'linuxhint.com' | base64
$ echo 'bGludXhoaW50LmNvbQo=' | base64 --decode
base64 input.txt > base64Data.txt
base64 -d base64Data.txt > original.txt
Error handling
SendGrid may return an error code when Attachment is too large, which is 413 status code. You can learn more about status codes returned by SendGrid API at this link: SendGrid Mail Error Codes
Top articles in this category:
- SendGrid emails in Spring Boot
- Sendgrid Dynamic Templates with Spring Boot
- Dialoglfow fulfillment with Spring Boot
- Elasticsearch with Spring Boot + Spring Data
- Basic Auth Security in Spring Boot 2
- Spring RestTemplate Basic Authentication
- Redis rate limiter in Spring Boot