使用JavaMail创建多部分

使用JavaMail创建多部分,java,jakarta-mail,mime,smime,Java,Jakarta Mail,Mime,Smime,我想创建一个MimeMessage,它必须有两个部分,如下图所示(第0部分和第2部分) 我试图使用下面的代码生成s/mime public static void main(String[] a) throws Exception { // create some properties and get the default Session Properties props = new Properties(); // props.put("mail.smtp.hos

我想创建一个
MimeMessage
,它必须有两个部分,如下图所示(第0部分和第2部分)

我试图使用下面的代码生成s/mime

public static void main(String[] a) throws Exception {

    // create some properties and get the default Session
    Properties props = new Properties();
    // props.put("mail.smtp.host", host);

    Session session = Session.getInstance(props, null);
    // session.setDebug(debug);
    MimeMessage msg = new MimeMessage(session);
    try {

        msg.addHeader("Content-Type", "multipart/signed; protocol=\"application/pkcs7-signature;");

        msg.setFrom(new InternetAddress(FROM_EMAIL));
        InternetAddress[] address = {new InternetAddress(
            TO_EMAIL)};
        msg.setRecipients(Message.RecipientType.TO, address);
        msg.setSubject("Test Subject");
        msg.setSentDate(new Date());

        // create and fill the first message part
        MimeBodyPart bodyPart1 = new MimeBodyPart();

        bodyPart1.setHeader("Content-Type", "text/html; charset=utf-8");
        bodyPart1.setContent("<b>Hello World</b>", "text/html");

        Multipart multiPart = new MimeMultipart();
        multiPart.addBodyPart(bodyPart1, 0);

        try (OutputStream str = Files.newOutputStream(Paths
                .get(UNSIGNED_MIME))) {
            bodyPart1.writeTo(str);
        }

        signMime();

        MimeBodyPart attachPart = new MimeBodyPart();

        String filename = SIGNED_VALUE;

        DataSource source = new FileDataSource(filename);

        attachPart.setDataHandler(new DataHandler(source));
        attachPart.setFileName("smime.p7s");
        attachPart.addHeader("Content-Type", "application/pkcs7-signature; name=smime.p7s;");
        attachPart.addHeader("Content-Transfer-Encoding", "base64");
        attachPart.addHeader("Content-Description", "S/MIME Cryptographic Signature");

        multiPart.addBodyPart(attachPart);

        msg.setContent(multiPart, "multipart/signed; protocol=\"application/pkcs7-signature\"; ");

        msg.saveChanges();
        try (OutputStream str = Files.newOutputStream(Paths
                .get(SIGNED_MIME))) {
            msg.writeTo(str);
        }

    } catch (MessagingException mex) {
        mex.printStackTrace();
        Exception ex = null;
        if ((ex = mex.getNextException()) != null) {
            ex.printStackTrace();
        }
    }
publicstaticvoidmain(字符串[]a)引发异常{
//创建一些属性并获取默认会话
Properties props=新属性();
//props.put(“mail.smtp.host”,host);
Session Session=Session.getInstance(props,null);
//setDebug(debug);
MimeMessage msg=新MimeMessage(会话);
试一试{
msg.addHeader(“内容类型”,“多部分/签名;协议=\“应用程序/pkcs7签名;”);
msg.setFrom(新的互联网地址(来自电子邮件));
InternetAddress[]地址={新的InternetAddress(
(电邮);;
msg.setRecipients(Message.RecipientType.TO,地址);
msg.setSubject(“测试对象”);
msg.setSentDate(新日期());
//创建并填充第一个消息部分
MimeBodyPart bodyPart1=新的MimeBodyPart();
bodyPart1.setHeader(“内容类型”,“text/html;charset=utf-8”);
bodyPart1.setContent(“helloworld”、“text/html”);
Multipart Multipart=新的MimeMultipart();
multiPart.addBodyPart(bodyPart1,0);
try(OutputStream str=Files.newOutputStream(路径
.get(未签名的\u MIME))){
正文部分1.写入(str);
}
signMime();
MimeBodyPart attachPart=新的MimeBodyPart();
字符串文件名=有符号的值;
DataSource source=新文件DataSource(文件名);
setDataHandler(新的DataHandler(源));
attachPart.setFileName(“smime.p7s”);
attachPart.addHeader(“内容类型”,“应用程序/pkcs7签名;名称=smime.p7s;”);
addHeader(“内容传输编码”、“base64”);
addHeader(“内容描述”、“S/MIME加密签名”);
多部件添加车身部件(附件部件);
msg.setContent(multiPart,“multiPart/signed;protocol=\“application/pkcs7 signature\”;);
msg.saveChanges();
try(OutputStream str=Files.newOutputStream(路径
.get(已签名){
msg.writeTo(str);
}
}捕获(消息例外mex){
mex.printStackTrace();
异常ex=null;
if((ex=mex.getNextException())!=null){
例如printStackTrace();
}
}
我使用了两个
MimeBodyPart
,但是我总是得到一个Part\u 0并生成如下所示的eml文件


您正在寻找的是。

我还没有尝试编译它,但您想要的是这样的。内部多部分是外部多部分的主体部分

    msg.setFrom(new InternetAddress(FROM_EMAIL));
    InternetAddress[] address = {new InternetAddress(
        TO_EMAIL)};
    msg.setRecipients(Message.RecipientType.TO, address);
    msg.setSubject("Test Subject");
    msg.setSentDate(new Date());

    MultipartSigned multiSigned = new MultipartSigned();

    // create and fill the first message part
    MimeBodyPart bodyPart1 = new MimeBodyPart();

    bodyPart1.setText("<b>Hello World</b>", "utf-8", "html");

    Multipart multiPart = new MimeMultipart();
    multiPart.addBodyPart(bodyPart1);

    // add other content to the inner multipart here

    MimeBodyPart body = new MimeBodyPart();
    body.setContent(multiPart);
    multiSigned.addBodyPart(body);

    try (OutputStream str = Files.newOutputStream(Paths
            .get(UNSIGNED_MIME))) {
        body.writeTo(str);
    }

    signMime();

    MimeBodyPart attachPart = new MimeBodyPart();

    String filename = SIGNED_VALUE;

    attachPart.attachFile(filename,
            "application/pkcs7-signature; name=smime.p7s", "base64");
    attachPart.setFileName("smime.p7s");
    attachPart.addHeader("Content-Description",
            "S/MIME Cryptographic Signature");

    multiSigned.addBodyPart(attachPart);
    msg.setContent(multiSigned);

    msg.saveChanges();

通过将更多功能移到MultipartSigned类中,您可以使其更简洁。

很有帮助,但如果我是海报,我将只使用第三方库作为最后手段。您好@DavidS:)我将检查@Bill Shannon firstDear@Bill的答案谢谢您的关注。这解决了我的问题。您好@Bill should我在msg.saveChanges()之前添加msg.setContent(multiSigned);因为当我尝试保存更改()时,它会给出一个错误“不平衡的引号字符串”。是的,对不起,我忘记了。
public class MultipartSigned extends MimeMultipart {
    public MultipartSigned() {
        super("signed");
        ContentType ct = new ContentType(contentType);
        ct.setParameter("protocol", "application/pkcs7-signature");
        contentType = ct.toString();
    }
}