无法在Java中分析此多部分mime消息正文

无法在Java中分析此多部分mime消息正文,java,jakarta-mail,mime,multipart,Java,Jakarta Mail,Mime,Multipart,我不是在写邮件应用程序,所以我不能访问所有的邮件头等等。我所知道的就是这个问题末尾的那块。我已经尝试使用JavaMail API来解析它,使用类似 Session s = Session.getDefaultInstance(new Properties()); InputStream is = new ByteArrayInputStream(<< String to parse >>); MimeMessage message = new MimeMessage(s,

我不是在写邮件应用程序,所以我不能访问所有的邮件头等等。我所知道的就是这个问题末尾的那块。我已经尝试使用JavaMail API来解析它,使用类似

Session s = Session.getDefaultInstance(new Properties());
InputStream is = new ByteArrayInputStream(<< String to parse >>);
MimeMessage message = new MimeMessage(s, is);
Multipart multipart = (Multipart) message.getContent();
会话s=Session.getDefaultInstance(新属性()); InputStream is=newbytearrayinputstream(>); MimeMessage message=新的MimeMessage(s,is); Multipart Multipart=(Multipart)message.getContent(); 但是,它只是告诉我message.getContent是一个字符串,而不是一个Multipart或MimeMultipart。另外,我并不需要整个JavaMail API的所有开销,我只需要将文本解析为各个部分。下面是一个例子:

This is a multi-part message in MIME format.\n\n------=_NextPart_000_005D_01CC73D5.3BA43FB0\nContent-Type: text/plain;\n\tcharset="iso-8859-1"\nContent-Transfer-Encoding: quoted-printable\n\nStuff:\n\n Please read this stuff at the beginning of each week. =\nFeel free to discuss it throughout the week.\n\n\n--=20\n\nMrs. Suzy M. Smith\n555-555-5555\nsuzy@suzy.com\n------=_NextPart_000_005D_01CC73D5.3BA43FB0\nContent-Type: text/html;\n\tcharset="iso-8859-1"\nContent-Transfer-Encoding: quoted-printable\n\n\n\n\n\n\n\n\n\nStuff:

\n=20\nPlease read this stuff at the beginning of each =\nweek. Feel=20\nfree to discuss it throughout the week.

\n
--

Mrs. Suzy M. Smith
555-555-5555
suzy@suzy.com\n\n------=_NextPart_000_005D_01CC73D5.3BA43FB0--\n\n 这是MIME格式的多部分消息。\n\n-----=\u NextPart\u 000\u 005D\u 01CC73D5.3BA43FB0\n内容类型:text/plain\n\tcharset=“iso-8859-1”\n内容传输编码:引用的可打印\n\nStuff:\n\n请在每周开始时阅读这些内容=\nFeel可以在一周内自由讨论。\n\n\n--=20\n\nMrs。苏西·M·史密斯\n555-555-5555\nsuzy@suzy.com\n-----=\u NextPart\u 000\u 005D\u 01CC73D5.3BA43FB0\n内容类型:text/html\n\tcharset=“iso-8859-1”\n内容传输编码:引用的可打印\n\n\n\n\n\n\n\n文件:

\n=20\n请在每周一读这些内容。Feel=20\n一周内可以自由讨论。

\n
--

苏西·M·史密斯夫人
555-555-5555
suzy@suzy.com\n\n-----=\u下一部分\u 000\u 005D\u 01CC73D5.3BA43FB0--\n\n
首先,我以您的示例消息为例,用换行符替换所有出现的
\n
,用制表符替换所有出现的
\t


然后,我从项目(的子项目)下载JAR,并执行GUI解析
org.apache.james.mime4j.samples.tree.MessageTree
,将上面转换的消息作为输入。显然,Mime4J能够解析消息并提取HTML消息部分。

您发布的文本有一些问题

它不是有效的多部分mime。检查哪一个虽然不规范,但仍然正确

未定义mime边界。来自维基百科示例:
内容类型:多部分/混合;boundary=“frontier”
显示边界为“frontier”。在您的示例中,“---=\u NextPart\u 000\u 005D\u 01CC73D5.3BA43FB0”是边界,但这只能通过扫描文本来确定(即mime格式不正确)。您需要指示正在向您传递mime内容的傻瓜,您还需要知道mime边界值,该值未在消息头中定义。如果您获得了消息的整个正文,您将拥有足够的内容,因为消息正文以
MIME Version:1.0
开头,后跟
内容类型:multipart/mixed;boundary=“frontier”
其中,frontier将替换为编码mime的边界值

如果发送尸体的人是一个傻瓜(因为猴子太挑剔,所以改为猴子-我的坏DwB),并且不会(很可能不知道如何)发送完整的尸体,那么可以通过扫描文本中以“-”(即--boundary--)开头和结尾的一行来推导边界。注意,我提到了一条“线”。终端边界实际上是“-boundary-->\n”


最后,你发布的内容有两个部分。第一部分似乎定义了在第二部分中发生的替换。如果这是真的,那么第一部分的内容类型:可能不是“text/plain”。也许是“公司名称/替代定义”之类的。这将允许多种(如未来的增强)替换格式。

可以从http请求创建mimultipart

javax.mail.internet.MimeMultipart m = new MimeMultipart(new ServletMultipartDataSource(httpRequest));

public class ServletMultipartDataSource implements DataSource {
    String contentType;
    InputStream inputStream;
    public ServletMultipartDataSource(ServletRequest request) throws IOException {
        inputStream = new SequenceInputStream(new ByteArrayInputStream("\n".getBytes()), request.getInputStream());
        contentType = request.getContentType();
    }
    public InputStream getInputStream() throws IOException {
        return inputStream;
    }
    public OutputStream getOutputStream() throws IOException {
        return null;
    }
    public String getContentType() {
        return contentType;
    }
    public String getName() {
        return "ServletMultipartDataSource";
    }
}
对于get submitted表单参数,需要解析BodyPart标题:

public String getStringParameter(String name) throws MessagingException, IOException {
    for (int i = 0; i < getCount(); i++) {
        BodyPart bodyPart = m.getBodyPart(i);
        String[] nameHeader = bodyPart.getHeader("Content-Disposition");
        if (nameHeader != null && content instanceof String) {
            for (String bodyName : nameHeader) {
                if (bodyName.contains("name=\"" + name + "\"")) return String.valueOf(bodyPart.getContent());
            }
        }
    }
    return null;
}
公共字符串getStringParameter(字符串名称)抛出MessaginException,IOException{
对于(int i=0;i
如果使用
javax.servlet.http.HttpServlet
接收消息,则必须使用
HttpServletRequests.getHeaders
获取http头内容类型的值。然后,您将使用
org.apache.james.mime4j.stream.MimeConfig.setHeadlessParsing
使用信息设置MimeConfig,以便它能够正确处理mime消息


您似乎正在使用
HttpServletRequest.getInputStream
读取请求的内容。返回的输入流仅在HTTP头之后包含消息内容(以空行终止)。这就是为什么您必须从HTTP头中提取内容类型,并使用setHeadlessParsing将其提供给解析器。

我下载了这些JAR并试用了它们。我创建了一个ContentHandler类并使用了MimeStreamParser.parse。在我的处理程序中,先调用startMessage,然后调用startHeader和endHeader,这很好,因为没有头。然后,调用body,然后调用endMessage。我希望在那里有一些开始和结束的身体部分。或者,body调用了两次,因为有两个部分?我按照上面DwB的建议在其中添加了一些头信息,而MimeStreamParser.parse现在工作得很好。谢谢你的信息。我不能+1你,因为我没有足够的代表…虽然信息量很大,但我真的无能为力。这篇课文就是以这种方式呈现给我的。我需要一种方法来解析它,如果没有现成的工具可以,我想我必须手工完成…按照你的建议,放入一些标题信息,vanje建议的解析器在下面工作