2011-01-04 35 views
7

utilizo el siguiente código para descargar el archivo adjunto del correo electrónico, pero le da la ClassCastException en la declaración de varias partes:electrónico de Java con el accesorio: ClassCastException en javax.mail.Multipart

Excepción en hilo de Java "principal" .lang.ClassCastException: com.sun.mail.imap.IMAPInputStream no se puede convertir a javax.mail.Multipart en ReadAttachment.main (ReadAttachment.java:52)

¿Cómo manejo IMAPInputStream?

Message messages[] = inbox.getMessages(); 

for (int j = 0; j < messages.length; j++) { 

    String mailType = messages[j].getContentType(); 

    System.out.println("-- Message " + (j + 1) + " --"); 

    System.out.println("SentDate : " + messages[j].getSentDate()); 
    System.out.println("From : " + messages[j].getFrom()[0]); 
    System.out.println("Subject : " + messages[j].getSubject());    
    System.out.println("Type :" + messages[j].getContentType()); 
    System.out.println("Attachment :" + messages[j].getFileName()); 

    Multipart mp = (Multipart) messages[j].getContent(); 
    .. 

    System.out.println(); 
} 

Respuesta

2

Sí, porque estás asumiendo que getContent() vuelve algo que implementa Multipart, y en este caso no lo hace (IMAPInputStream extiende InputStream).

Tu código debe tener en cuenta esta posibilidad.

+0

Gracias skaffman !! –

2

El objeto devuelto por getContent depende del tipo de mensaje. Solo será Multipart si el tipo de mensaje es multipart. Se podría hacer una comprobación de si para mirar el tipo MIME ...

if(messages[j].getContentType().equals("multipart")) { 
    //Do your cast and stuff 
} else { 
    //This message isn't a multipart message, maybe just skip it. 
} 

Por supuesto que implica el uso de cuerdas mágicas. Una solución más sofisticada sería buscar en la API de DataHandler y usar el método getDataHandler() en el mensaje. Lamentablemente, no sé mucho sobre esa API.

4

El método getContent devuelve el contenido como un objeto Java y su tipo, por supuesto, depende del contenido en sí.

El objeto que se devuelve para el contenido "text/plain" suele ser un objeto String.
El objeto devuelto para un contenido "multiparte" siempre es una subclase de de varias partes.
Para tipos de contenido que son desconocidos para el sistema DataHandler, se devuelve una secuencia de entrada como el contenido .

visto en la Java Apache Cocoon source code*:

Object objRef = msg.getContent(); 
if (!(objRef instanceof Multipart)) { 
    String message = "This Message is not a multipart message!"; 
    getLogger().warn(message); 
    return; 
} 
Multipart multipart = (Multipart) objRef; 

* No tomo la responsabilidad por el posible mal uso de instanceof

+0

Gracias por su amable ayuda systempuntoout !!! –

+0

@Karth si esta respuesta le resultó útil, puede modificarla o marcarla como aceptada – systempuntoout

3

OK. Creo que el verdadero problema aquí es que, aunque debería verificar el tipo de objeto que está recibiendo ... aún podría ser IMAPInputStream cuando no debería ser así.

He estado insistiendo en esto durante más de dos días.

El problema subyacente es a menudo que Java Mail API hace algo muy tonto, intenta leer en un archivo llamado mailcap que no siempre está disponible si se ha cambiado el cargador de clases. Esto es particularmente complicado en mi caso porque estoy lidiando con paquetes OSGi y no parece tener control directo sobre qué cargador estoy usando ... pero estoy divagando.

Encontré 'una corrección' ... quizás EL ARREGLO después de revisar el código fuente de Java Mail API como último recurso.

 // Set up our Mailcap entries. This will allow the JAF 
    // to locate our viewers. 
    File capfile = new File("/path/to/mailcap"); 
    if (!capfile.isFile()) { 
    System.out.println(
     "Cannot locate the \"simple.mailcap\" file."); 
    System.exit(1); 
    } 

    CommandMap.setDefaultCommandMap(new MailcapCommandMap(
    new FileInputStream(capfile))); 

he estado buscando en Google por días y encontró decenas de personas con el mismo problema y varios ruta de clases, hilo, sugerencias cargador de clases. Pero esto es lo único que funcionó para mí y es relativamente simple. De ahí publicar esto en lo que parece ser el problema relacionado más cercano con cierto ímpetu. UF.

3

He solucionado este error agregando las siguientes líneas de código. Hay algo mal con MailCap, javamail no puede encontrar un controlador para la parte multiparte/mixta, por lo que este bit debe agregarse. Esto resolvió mi problema. Espero que ayude a alguien por ahí.

MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 
CommandMap.setDefaultCommandMap(mc); 

¡Salud!

+0

Estoy tratando de recibir correos electrónicos del servidor de gmail usando jdeveloper. Intenté implementar su solución, pero no puedo importar javax.activation. * Consulte esta publicación para obtener más información https://stackoverflow.com/questions/38436576/unable-to-import-javax-activation-in- jdeveloper-for-maf. Por favor, ayúdenme –

+0

@HellsGuardian Ha pasado mucho tiempo desde que trabajé en esto, por lo que no puedo proporcionar ninguna entrada. – jagmohan

5

Tuve el mismo problema con JavaMail 1.5.1 y OSGi. El uso de msg.getContent() siempre devolvía un InputStream cuando se lo llamaba desde un paquete OSGi mientras funcionaba perfectamente cuando se lo llamaba desde un simple programa de prueba de Java.

Ajuste del defecto CommandMap no funcionó para mí, pero he encontrado una solución a este problema:

https://www.java.net/node/705585

ClassLoader tcl = Thread.currentThread().getContextClassLoader(); 
try { 
    Thread.currentThread().setContextClassLoader(javax.mail.Session.class.getClassLoader()); 
    // now call JavaMail API 
    // ... 
} finally { 
    Thread.currentThread().setContextClassLoader(tcl); 
} 
Cuestiones relacionadas