Неподдерживаемый тип данных при получении изображений в формате JPG - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь получить встроенные изображения письма, для которого у меня есть следующий код:

protected void setCidAttachments(Message message, MensajeEmail mensajeEmail) {

    try {

        MimeMultipart mimeMultipart = (MimeMultipart) message.getDataHandler().getContent();

        for (int k = 0; k < mimeMultipart.getCount(); k++) {

            MimeBodyPart part = (MimeBodyPart) mimeMultipart.getBodyPart(k);
            processPart(part, mensajeEmail);

        }

    }

    catch (Exception e) {
        log.error("Error obtendo adxuntos con cid", e);
    }

}

private void processPart (BodyPart part, MensajeEmail mensajeEmail) throws MessagingException, IOException {

    String type = getContentType(part);
    StringBuilder content = new StringBuilder(mensajeEmail.getContenido());

    if (isImage(type) && part.getDataHandler() != null && part.getDataHandler().getContent() != null) {

        if (part.getDataHandler().getContent() instanceof MimeMultipart) {

            MimeMultipart p = (MimeMultipart) part.getDataHandler().getContent();

            for (int i = 0; i < p.getCount(); i++) {

                BodyPart subpart = p.getBodyPart(i != p.getCount() - 1 ? i + 1 : i);
                processPart(subpart, mensajeEmail);

            }

        } else {

            mensajeEmail.setContenido(getInlineImage(part, content));

        }

    }

}

private String getInlineImage (BodyPart part, StringBuilder content) throws MessagingException, IOException {

    Base64 decoder64 = new Base64();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    // Get type

    String type = getContentType(part);

    // Get Content-ID

    String contentId = getContentId(part);

    // Replace

    if (contentId.length() > 0) {

        part.getDataHandler().writeTo(bos);
        int start = content.indexOf("src=\"cid:" + contentId + "\"") + 5;

        if (start > 4) {

            int length = contentId.length() + 4;
            content.replace(start, start + length, "data:" + (isImage(type) ? type : "image/png;") + " base64," + decoder64.encodeToString(bos.toByteArray()));

        }

    }

    bos.close();

    return content.toString();

}

private String getContentId (BodyPart part) throws MessagingException {

    Enumeration headers = part.getAllHeaders();

    while (headers.hasMoreElements()) {

        Header header = (Header)headers.nextElement();

        if (header.getName().equalsIgnoreCase("Content-ID"))
            return cleanContentId(header.getValue());

    }

    return "";

}

private String getContentType (BodyPart part) throws MessagingException {

    return part.getContentType().split(" ")[0];

}

private boolean isImage (String mime) {

    return !mime.equals("text/html;") && !mime.equals("text/plain;");

}

private String cleanContentId (String contentId) {

    if (contentId.charAt(0) == '<') contentId = contentId.substring(1, contentId.length() - 1);
    return contentId;

}

Это прекрасно работает при отправке изображений PNG (что заставляет меня думать, что мой код действительно правильно). Однако, когда я пытаюсь отправить изображение JPG, я получаю следующее исключение:

javax.activation.UnsupportedDataTypeException: Unknown image type image/jpeg; name=sony-car-796x418.jpg
at org.apache.geronimo.activation.handlers.AbstractImageHandler.getContent(AbstractImageHandler.java:57)
at javax.activation.DataSourceDataContentHandler.getContent(DataHandler.java:795)
at javax.activation.DataHandler.getContent(DataHandler.java:542)
at es.enxenio.fcpw.plinper.daemons.email.AbstractProtocoloObtencionEmail.processPart(AbstractProtocoloObtencionEmail.java:378)

...

Действительно ли фреймворк не может работать с изображениями JPG? Есть ли способ, как я могу это исправить?

РЕДАКТИРОВАТЬ: Gmail даже не позволяет мне отправлять изображения JPG, так что, вероятно, это не очень распространенный формат для почтовых изображений, что заставляет меня думать, что не может быть широко реализовано и что может быть причиной того, что Java не может работать с ним

1 Ответ

0 голосов
/ 03 марта 2020

Я нашел проблему. Эта строка

if (isImage(type) && part.getDataHandler() != null && part.getDataHandler().getContent()

не должна проверять, является ли тип изображением, но является ли он составным. В противном случае мы могли бы обрабатывать изображение jpg как составную часть. По некоторым причинам изображения PNG не возражают против этого, и именно поэтому он работал. Вот измененные части кода:

protected void setCidAttachments(Message message, MensajeEmail mensajeEmail) {

    try {

        processPart(message, mensajeEmail);

    }

    catch (Exception e) {
        log.error("Error obtendo adxuntos con cid", e);
    }

}

private void processPart(Part part, MensajeEmail mensajeEmail) throws MessagingException, IOException {

    String type = getContentType(part);
    StringBuilder content = new StringBuilder(mensajeEmail.getContenido());

    if (isMultipart(type) && part.getDataHandler() != null && part.getDataHandler().getContent() != null && part.getDataHandler().getContent() instanceof MimeMultipart) {

        MimeMultipart multipart = (MimeMultipart) part.getDataHandler().getContent();

        for (int i = 0; i < multipart.getCount(); i++) {

            BodyPart subpart = multipart.getBodyPart(i);
            processPart(subpart, mensajeEmail);

        }

    } 

    else {

        mensajeEmail.setContenido(getInlineImage(part, content));

    }

}

private boolean isMultipart(String mime) {

    return (Pattern.matches("multipart/.*", mime));

}
...