0

This is the first time I've written something in Java so I'm leaning slowly but I am hard stuck on how to fix this issue. I'm having an issue getting the images that a user inserts into my JEditorPane editerPane to send as an embedded image instead of a file attachment in the email.

    private static void embedAndSendEmail(JEditorPane editorPane) throws IOException, BadLocationException, URISyntaxException {
        HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
        ElementIterator iterator = new ElementIterator(doc);
        Element element;

            // Collect images to embed
            List<File> imageFiles = new ArrayList<>();
            while ((element = iterator.next()) != null) {
                AttributeSet attrs = element.getAttributes();
                Object nameAttr = attrs.getAttribute(StyleConstants.NameAttribute);

                if (nameAttr instanceof HTML.Tag) {
                    HTML.Tag tag = (HTML.Tag) nameAttr;

                    if (tag == HTML.Tag.IMG) {
                        String src = (String) attrs.getAttribute(HTML.Attribute.SRC);
                        if (src != null && src.startsWith("file:///")) {
                            // Read image data from editor pane
                            InputStream inputStream = new URL(src).openStream();
                            byte[] imageData = inputStream.readAllBytes();
                            String base64Image = Base64.getEncoder().encodeToString(imageData);

                            // Replace src attribute with base64 data
                            String newSrc = "data:image/png;base64," + base64Image;
                            doc.setInnerHTML(element, "<img src=\"" + newSrc + "\">");

                            // Add image file to the list (for sending email later)
                            String filePath = new URI(src).getPath(); // Convert URL to file path
                            imageFiles.add(new File(filePath));
                        }
                    }
                }
            }

    }

I've tried to go the Base64 route even though I know it's not as reliable as using Mimebodypart() but I am trying to send out the users inserted image.

Below I am putting the code that interacts with each other to get the email sent out minus the panels and buttons. The code below is trying to embed those images but has the same result of it sending as an attachment.

public class testing {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Mailgun");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1280, 720);
        
        
        //Listener to insert an image upon clicking
        imageInsert.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileFilter(new FileNameExtensionFilter("Images", "jpg", "jpeg", "png", "gif"));
            if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
                File imageFile = fileChooser.getSelectedFile();
                insertImage(editorPane, imageFile);
            }
        });
        
        JButton sendButton = new JButton("Send Email");
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String to = emailField.getText();
                String subject = subjectField.getText();
                String content = "<html><body>"                
                        + editorPane.getText()
                        +"</body></html>";
                //Made to not allow an email to be sent till fields are not empty
                if (to.isEmpty() || subject.isEmpty() || content.isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Please fill in all fields.");
                    return;
                }

                try {
                    sendEmail(to, subject, content, imageFiles);
                } catch (IOException | MessagingException e1) {
                    e1.printStackTrace();
                }
            }
        

}
        private static void sendEmail(String to, String subject, String content, List<File> imageFiles) throws IOException, MessagingException {
            final String username = "";
            final   String password = "";
            Properties properties = new Properties();
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.starttls.enable", "true");
            properties.put("mail.smtp.host", "smtp.mailgun.com");
            properties.put("mail.smtp.port", "587");

            Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
            MimeMultipart multipart = new MimeMultipart("related");
            

            try {
                for (File imageFile : imageFiles) {
                    MimeBodyPart imagePart = new MimeBodyPart();
                    DataSource ds = new FileDataSource(imageFile);
                    imagePart.setDataHandler(new DataHandler(ds));
                    imagePart.setHeader("Content-ID", "<image>");
                    imagePart.setDisposition(MimeBodyPart.INLINE);
                    imagePart.setFileName(imageFile.getName());
                    multipart.addBodyPart(imagePart);
                }
                

                MimeMessage message = new MimeMessage(session);
                message.setFrom(new InternetAddress(username));
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                message.setSubject(subject);
                


                // Set the content of the message to the multipart
                message.setContent(multipart);

                // Send message
                Transport.send(message);
                JOptionPane.showMessageDialog(null, "Email sent successfully.");
            } catch (MessagingException e) {
                JOptionPane.showMessageDialog(null, "Failed to send email: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

Truly don't know where to go from here, any advice is greatly appreciated!

0

1 Answer 1

1

This is just a proof of concept.

Test.java

package com.example.mail;

import jakarta.mail.Session;
import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
import jakarta.mail.BodyPart;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeMultipart;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws MessagingException, IOException {
        String to =  "[email protected]";
        String subject1 = "Testing Subject1";
        String subject2 = "Testing Subject2";
        /*
        String content = "<html><body>"
                + "<h1>Hello</h1>"
                +"</body></html>";
         */
        String content = "<html><body>"
                + "<H1>Hello</H1>"
                + "<img src=\"cid:image1\"><p/>"
                + "<H1>Hello2</H1>"
                + "<img src=\"cid:image2\"><p/>"
                +"</body></html>";

        List<File> imageFiles =new ArrayList<File>();
        imageFiles.add(new File("/home/demo/Documents/Examples_JakartaEE/JakartaMail/src/main/resources/icon01.png"));
        imageFiles.add(new File("/home/demo/Documents/Examples_JakartaEE/JakartaMail/src/main/resources/icon02.png"));

        sendEmail(to, subject1, content, imageFiles);
        sendEmail2(to, subject2, content, imageFiles);

    }

    public static void sendEmail2(String to, String subject, String content, List<File> imageFiles) throws IOException, MessagingException {
        final String username = "[email protected]";
        final String password = "1234";

        String host = "smtp.james.local";  //smtp.mailgun.com
        Properties properties = new Properties();
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.ssl.trust", host);

        Session session = Session.getInstance(properties, new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        MimeMultipart multipart = new MimeMultipart("related");
        // first part (the html)
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setContent(content, "text/html");
        // add it
        multipart.addBodyPart(messageBodyPart);

        int imageCount =0;
        try {
            for (File imageFile : imageFiles) {
                imageCount++;
                //MimeBodyPart imagePart = new MimeBodyPart();
                BodyPart imagePart = new MimeBodyPart();
                DataSource ds = new FileDataSource(imageFile);
                imagePart.setDataHandler(new DataHandler(ds));
                imagePart.setHeader("Content-ID", "<image"+ imageCount+">");
                //imagePart.setDisposition(MimeBodyPart.INLINE);
                //imagePart.setFileName(imageFile.getName());
                multipart.addBodyPart(imagePart);
            }

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject(subject);

            // Set the content of the message to the multipart
            message.setContent(multipart);

            // Send message
            Transport.send(message);
            //JOptionPane.showMessageDialog(null, "Email sent successfully.");
        } catch (MessagingException e) {
            //JOptionPane.showMessageDialog(null, "Failed to send email: " + e.getMessage());
            e.printStackTrace();
        }
    }


   public static void sendEmail(String to, String subject, String content, List<File> imageFiles) throws IOException, MessagingException {
       final String username = "[email protected]";
       final String password = "1234";

       String host = "smtp.james.local";  //smtp.mailgun.com
       Properties properties = new Properties();
       properties.put("mail.smtp.auth", "true");
       properties.put("mail.smtp.starttls.enable", "true");
       properties.put("mail.smtp.host", host);
       properties.put("mail.smtp.port", "587");
       properties.put("mail.smtp.ssl.trust", host);


        Session session = Session.getInstance(properties, new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        MimeMultipart multipart = new MimeMultipart("related");


        try {
            for (File imageFile : imageFiles) {
                MimeBodyPart imagePart = new MimeBodyPart();
                DataSource ds = new FileDataSource(imageFile);
                imagePart.setDataHandler(new DataHandler(ds));
                imagePart.setHeader("Content-ID", "<image>");
                imagePart.setDisposition(MimeBodyPart.INLINE);
                imagePart.setFileName(imageFile.getName());
                multipart.addBodyPart(imagePart);
            }


            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject(subject);



            // Set the content of the message to the multipart
            message.setContent(multipart);

            // Send message
            Transport.send(message);
            //JOptionPane.showMessageDialog(null, "Email sent successfully.");
        } catch (MessagingException e) {
            //JOptionPane.showMessageDialog(null, "Failed to send email: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

There is no GUI code, just simple Hard code for testing.

  • (1) sendEmail is your version
  • (2) sendEmail2 is the modified version.

The image needs to be added to content using cid.

Note: To embed an image in the content, use <img src="cid:image1"> where the name of cid must be the same as the name of the subsequent image (image1, image2,...)

Modification item 1:

//MimeBodyPart imagePart = new MimeBodyPart();

BodyPart imagePart = new MimeBodyPart();

Modification item 2:

//imagePart.setHeader("Content-ID", "<image>");

imagePart.setHeader("Content-ID", "<image"+ imageCount+">");

Modification item 3: remove two.

//imagePart.setDisposition(MimeBodyPart.INLINE);
                //imagePart.setFileName(imageFile.getName());

sendmail - Only one image will be displayed in the content, and two attachment files will appear in Mail.

enter image description here

sendmail2 - 2 images are displayed in the content, and the attachment file does not appear in Mail.

enter image description here

Test EMAIL Environment : Apache James

I use Docker to run Apache James Mail Server.

docker run \
  --rm \
  -it \
  -p 143:143 \
  -p 25:25 \
  -p 4000:4000 \
  -p 465:465 \
  -p 587:587 \
  -p 80:80 \
  -p 8000:8000 \
  -p 993:993 \
  apache/james:demo-3.8.1

Built in User Accounts:

password: 1234

Not the answer you're looking for? Browse other questions tagged or ask your own question.