{"id":3686,"date":"2026-04-20T09:29:34","date_gmt":"2026-04-20T13:29:34","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3686"},"modified":"2026-04-20T09:29:34","modified_gmt":"2026-04-20T13:29:34","slug":"sending-emails-with-aws-simple-email-service-ses-and-attachments","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/aws\/sending-emails-with-aws-simple-email-service-ses-and-attachments\/","title":{"rendered":"Sending Emails with AWS Simple Email Service (SES) and Attachments"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>In this blog article, we\u2019ll delve into using Amazon Simple Email Service (SES) to send emails, both with and without attachments, directly from your applications. SES is a cost-effective, flexible, and scalable email service offered by AWS.<\/p>\n<p>Let\u2019s explore how to leverage its capabilities.<\/p>\n<p><strong>1. Set up AWS SES<\/strong><\/p>\n<ul>\n<li>If you haven\u2019t already, create an AWS account.<\/li>\n<li>Navigate to the SES console and verify your email address or domain. This is important, especially if you\u2019re in the SES sandbox, to ensure deliverability.<\/li>\n<li>Obtain your AWS access key ID and secret access key. These credentials will be used to authenticate your application with AWS.<\/li>\n<\/ul>\n<p><strong>2. Include the AWS SDK in Your Project<\/strong><\/p>\n<ul>\n<li>Add the AWS SDK for Java to your project. If you\u2019re using Maven, include the following dependency in your <code>pom.xml<\/code>:<\/li>\n<\/ul>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;com.amazonaws&lt;\/groupId&gt;\n    &lt;artifactId&gt;aws-java-sdk-ses&lt;\/artifactId&gt;\n    &lt;version&gt;1.12.540&lt;\/version&gt; \n&lt;\/dependency&gt;\n<\/code><\/pre>\n<ul>\n<li>Adjust the version if needed.<\/li>\n<\/ul>\n<p><strong>3. Create the Email Service<\/strong><\/p>\n<ul>\n<li>Let\u2019s craft a service to handle email sending using the AWS SDK.<\/li>\n<\/ul>\n<pre><code class=\"language-java\">import com.amazonaws.auth.AWSStaticCredentialsProvider;\nimport com.amazonaws.auth.BasicAWSCredentials;\nimport com.amazonaws.regions.Regions;\nimport com.amazonaws.services.simpleemail.AmazonSimpleEmailService;\nimport com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;\nimport com.amazonaws.services.simpleemail.model.*;\nimport org.springframework.stereotype.Service;\n\nimport javax.activation.DataHandler;\nimport javax.activation.DataSource;\nimport javax.activation.FileDataSource;\nimport javax.mail.Message;\nimport javax.mail.MessagingException;\nimport javax.mail.Session;\nimport javax.mail.internet.InternetAddress;\nimport javax.mail.internet.MimeBodyPart;\nimport javax.mail.internet.MimeMessage;\nimport javax.mail.internet.MimeMultipart;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.Properties;\n\n@Service\npublic class AwsSesEmailService {\n\n    private final AmazonSimpleEmailService sesClient;\n\n    public AwsSesEmailService() {\n        BasicAWSCredentials credentials = new BasicAWSCredentials(&quot;your-access-key-id&quot;, &quot;your-secret-access-key&quot;);\n        sesClient = AmazonSimpleEmailServiceClientBuilder.standard()\n                .withCredentials(new AWSStaticCredentialsProvider(credentials))\n                .withRegion(Regions.YOUR_PREFERRED_REGION) \n                .build();\n    }\n\n    public void sendSimpleEmail(String to, String subject, String text) {\n        SendEmailRequest request = new SendEmailRequest()\n                .withDestination(new Destination().withToAddresses(to))\n                .withMessage(new Message()\n                        .withBody(new Body().withText(new Content().withCharset(&quot;UTF-8&quot;).withData(text)))\n                        .withSubject(new Content().withCharset(&quot;UTF-8&quot;).withData(subject)))\n                .withSource(&quot;your-verified-email@example.com&quot;); \n\n        sesClient.sendEmail(request);\n    }\n\n    public void sendEmailWithAttachment(String to, String subject, String text, String attachmentPath) throws MessagingException, IOException {\n        Session session = Session.getDefaultInstance(new Properties());\n        MimeMessage message = new MimeMessage(session);\n\n        message.setSubject(subject, &quot;UTF-8&quot;);\n        message.setFrom(new InternetAddress(&quot;your-verified-email@example.com&quot;));\n        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));\n\n        MimeBodyPart textPart = new MimeBodyPart();\n        textPart.setContent(text, &quot;text\/plain; charset=UTF-8&quot;);\n\n        MimeBodyPart attachmentPart = new MimeBodyPart();\n        DataSource source = new FileDataSource(attachmentPath);\n        attachmentPart.setDataHandler(new DataHandler(source));\n        attachmentPart.setFileName(source.getName());\n\n        MimeMultipart multipart = new MimeMultipart();\n        multipart.addBodyPart(textPart);\n        multipart.addBodyPart(attachmentPart);\n\n        message.setContent(multipart);\n\n        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        message.writeTo(outputStream);\n\n        RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));\n\n        SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage);\n        sesClient.sendRawEmail(rawEmailRequest);\n    }\n}\n<\/code><\/pre>\n<ul>\n<li>Replace the placeholders with your actual AWS credentials and verified email address.<\/li>\n<li>Choose the appropriate AWS region for your SES setup.<\/li>\n<\/ul>\n<p><strong>4. Use the Email Service<\/strong><\/p>\n<ul>\n<li>Similar to the previous example, you can autowire this <code>AwsSesEmailService<\/code> and use it to send emails.<\/li>\n<\/ul>\n<pre><code class=\"language-java\">@Autowired\nprivate AwsSesEmailService awsSesEmailService;\n\n\/\/ ...\n\nawsSesEmailService.sendSimpleEmail(&quot;recipient@example.com&quot;, &quot;Hello from SES&quot;, &quot;This is a test email using AWS SES.&quot;);\n\n\/\/ ...\n\ntry {\n    awsSesEmailService.sendEmailWithAttachment(&quot;recipient@example.com&quot;, &quot;SES Report&quot;, &quot;Please find the attached report.&quot;, &quot;\/path\/to\/report.pdf&quot;);\n} catch (MessagingException | IOException e) {\n    \/\/ Handle exceptions\n}\n<\/code><\/pre>\n<p><strong>Important Considerations:<\/strong><\/p>\n<ul>\n<li>Make sure your AWS credentials are secure and not exposed in your code or version control.<\/li>\n<li>Be mindful of SES sending limits, especially if you\u2019re in the sandbox.<\/li>\n<li>Monitor your email sending reputation to maintain good deliverability.<\/li>\n<li>Implement error handling and logging to troubleshoot any issues that may arise.<\/li>\n<\/ul>\n<p>By following these steps, you can effectively utilize AWS SES to send emails, with or without attachments, directly from your Java applications. SES provides a robust and scalable solution for managing your email communication needs.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":3687,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[442],"tags":[431,69,319],"series":[],"class_list":["post-3686","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aws","tag-aws","tag-java-2","tag-spring"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-4487083_1280-jpg.avif","jetpack-related-posts":[{"id":3680,"url":"https:\/\/www.mymiller.name\/wordpress\/aws\/sending-sms-and-mms-messages-with-aws-sns-and-java-spring-integration\/","url_meta":{"origin":3686,"position":0},"title":"Sending SMS and MMS Messages with AWS SNS and Java (Spring Integration)","author":"Jeffery Miller","date":"April 20, 2026","format":false,"excerpt":"AWS Simple Notification Service (SNS) provides a robust platform for sending notifications across various channels, including SMS and MMS. Let\u2019s explore how to implement this functionality using Java within a Spring framework. Prerequisites AWS Account: An active AWS account is necessary. AWS SDK for Java: Make sure you have the\u2026","rel":"","context":"In &quot;AWS&quot;","block_context":{"text":"AWS","link":"https:\/\/www.mymiller.name\/wordpress\/category\/aws\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/smartphone-3152679_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/smartphone-3152679_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/smartphone-3152679_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/smartphone-3152679_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/smartphone-3152679_1280-jpg.avif 3x"},"classes":[]},{"id":3683,"url":"https:\/\/www.mymiller.name\/wordpress\/spring\/sending-emails-in-java-spring-with-attachments-using-javamail\/","url_meta":{"origin":3686,"position":1},"title":"Sending Emails in Java Spring with Attachments using JavaMail","author":"Jeffery Miller","date":"April 20, 2026","format":false,"excerpt":"In this blog post, we\u2019ll delve into the process of creating a Java Spring service that leverages JavaMail to send emails, both with and without attachments. This capability is crucial for many web applications, from sending user registration confirmations to delivering reports and notifications. Let\u2019s get started. 1. Set up\u2026","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-3597088_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-3597088_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-3597088_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-3597088_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/e-mail-3597088_1280-jpg.avif 3x"},"classes":[]},{"id":3903,"url":"https:\/\/www.mymiller.name\/wordpress\/docker\/the-s3-local-dev-trick-using-minio-to-simplify-cloud-native-developmen\/","url_meta":{"origin":3686,"position":2},"title":"The S3 Local Dev Trick: Using MinIO to Simplify Cloud-Native Developmen","author":"Jeffery Miller","date":"August 25, 2025","format":false,"excerpt":"As a software architect building cloud-native solutions, you know that working with cloud services like AWS S3 can be a bit tricky in a local development environment. You don't want to constantly connect to a remote bucket, and setting up complex local testing environments can be a pain. But what\u2026","rel":"","context":"In &quot;Docker&quot;","block_context":{"text":"Docker","link":"https:\/\/www.mymiller.name\/wordpress\/category\/docker\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-9268117_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-9268117_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-9268117_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-9268117_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-9268117_1280.avif 3x"},"classes":[]},{"id":3744,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_config\/3744\/","url_meta":{"origin":3686,"position":3},"title":"Spring Cloud Config: Choosing the Right Backend Storage","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"Spring Cloud Config offers a flexible way to manage your application\u2019s configuration. A crucial step is selecting the right backend to store your configuration data. Let\u2019s explore popular options, their pros and cons, configuration details, and the necessary dependencies for Maven and Gradle. 1. Git Pros: Version Control: Leverage Git\u2019s\u2026","rel":"","context":"In &quot;Spring Config&quot;","block_context":{"text":"Spring Config","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_config\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/woman-8696271_640.jpg?fit=438%2C640&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":3868,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_events\/streamlining-user-events-integrating-aws-cognito-with-kafka\/","url_meta":{"origin":3686,"position":4},"title":"Streamlining User Events: Integrating AWS Cognito with Kafka","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In modern application architectures, understanding user behavior is crucial. Tracking events like logins, logouts, failed login attempts, and signups can provide valuable insights for analytics, security monitoring, and personalized user experiences. This post will guide you through the process of configuring AWS Cognito to send these events to an Apache\u2026","rel":"","context":"In &quot;Spring Events&quot;","block_context":{"text":"Spring Events","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_events\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/binary-7206874_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/binary-7206874_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/binary-7206874_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/binary-7206874_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/binary-7206874_1280.avif 3x"},"classes":[]},{"id":3502,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/spring-data-jpa-for-dummies-persisting-data-like-a-pro\/","url_meta":{"origin":3686,"position":5},"title":"Spring Data JPA for Dummies: Persisting Data Like a Pro","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Ever feel bogged down by writing tons of code just to interact with your database? If you're a Java developer working with relational databases, Spring Data JPA is your new best friend. This blog post will give you a beginner-friendly introduction to Spring Data JPA, showing you how to save\u2026","rel":"","context":"In &quot;Spring Databases&quot;","block_context":{"text":"Spring Databases","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_databases\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/binary-2904980_1280.jpg?fit=1200%2C674&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/binary-2904980_1280.jpg?fit=1200%2C674&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/binary-2904980_1280.jpg?fit=1200%2C674&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/binary-2904980_1280.jpg?fit=1200%2C674&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/binary-2904980_1280.jpg?fit=1200%2C674&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3686","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3686"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3686\/revisions"}],"predecessor-version":[{"id":3688,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3686\/revisions\/3688"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3687"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3686"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}