首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

java 发 email 附件有关问题

2012-12-19 
java 发 email 附件问题在doc, png, csv 我试了,都没有问题但是xml 就不行了。javax.mail.MessagingExcepti

java 发 email 附件问题
在doc, png, csv 我试了,都没有问题
但是xml 就不行了。

javax.mail.MessagingException: IOException while sending message;
  nested exception is:
java.io.IOException: "text/xml" DataContentHandler requires String object, was given object of type class [B
###javax.mail.MessagingException: IOException while sending message;
  nested exception is:
java.io.IOException: "text/xml" DataContentHandler requires String object, was given object of type class [B
---End---
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:566)
at com.amazon.ses.SendEmail.startSendEmail(SendEmail.java:118)
at com.amazon.ses.LoginSalesforce.login(LoginSalesforce.java:91)
at com.amazon.ses.LoginSalesforce.login(LoginSalesforce.java:47)
at com.amazon.ses.test.TestLogin.testSendDocuments(TestLogin.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
[最优解释]
java.io.IOException: "text/xml" DataContentHandler requires String object, was given object of type class [B

粗一看,DataContentHandler接收的处理对象是不是需要一个类型转换的过程,当前是class [B类型,需要的是String型

可能的话,可以看下这个类SMTPTransport.java:566
[其他解释]
楼主  我的邮件发送的时候 错误为 554 DT:SPM查了下说是服务器标记成垃圾右键发送不出去   有没有解决办法源码如下

import javax.swing.JFrame;
import javax.swing.JFileChooser;
import java.awt.Container;
import java.awt.BorderLayout;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JLabel; 
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import java.io.FileOutputStream;
import javax.mail.Transport;


class JWF extends JFrame
{
private JLabel Label[]={new JLabel("from:"),new JLabel("to:"),new JLabel("Subject")};
private JTextField Tfield[]={new JTextField("laoziaimenglia@163.com",15),new JTextField("104621235@qq.com",15),new JTextField("test",15)};
private JPanel panel[]={new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel()};
private JButton button[]={new JButton("发送"),new JButton("清除"),new JButton("退出")};
private JTextArea textarea=new JTextArea("test");
private JScrollPane scrollpane=new JScrollPane(textarea);
private JButton button1=new JButton("路径选择");
private JTextField lujing=new JTextField(25);
private JPanel lujingmk=new JPanel();
private String from;
private String to;
private String subject;
private String protocol="smtp";
private String body="你好  最近你在干嘛"+
"<img src="cid:157222.jpg">";
;
private String pw="woaimenglia";
    private String user="laoziaimenglia";
private String host="smtp.163.com";

      public JWF()
      {
            lujingmk.setLayout(new FlowLayout());
      Container c=getContentPane();
      c.setLayout(new BorderLayout());
           panel[0].setLayout(new FlowLayout());
           panel[1].setLayout(new FlowLayout());
           
      for(int i=0;i<3;i++)
      {
        panel[0].add(Label[i]);
        panel[0].add(Tfield[i]);
        c.add(panel[0],BorderLayout.NORTH);
      }
      panel[2].setLayout(new BorderLayout());
      lujingmk.add(lujing);
      lujingmk.add(button1);
      panel[2].add(lujingmk,BorderLayout.NORTH);
      panel[2].add(scrollpane,BorderLayout.CENTER);
          c.add(panel[2],BorderLayout.CENTER);
           for(int k=0;k<3;k++)
         panel[1].add(button[k]);
           c.add(panel[1],BorderLayout.SOUTH);
           /////////////////////////////////监听
           button[0].addActionListener(new ActionListener()
           {
  public void actionPerformed(ActionEvent e){
  from=Tfield[0].getText();
  to=Tfield[1].getText();
  subject=Tfield[2].getText();
 // body=textarea.getText();


  try{
    mail m1=new mail();
  }
  catch(Exception ee)
  {
  ee.printStackTrace();
  }
}
           });
           button[1].addActionListener(new ActionListener()
           {
             public void actionPerformed(ActionEvent e)
             {
             textarea.setText("");
             }
           });
           button[2].addActionListener(new ActionListener()
           {
           public void actionPerformed(ActionEvent e)
           {
           System.exit(0);
           }
           });
           button1.addActionListener(new ActionListener()
           {
           public void actionPerformed(ActionEvent e)
           {
           JFileChooser chooser = new JFileChooser("./");
                   FileNameExtensionFilter filter = new FileNameExtensionFilter(
                    "文本文档", "txt");
                   chooser.setFileFilter(filter);
                   int returnVal = chooser.showOpenDialog(panel[2]);
                   if(returnVal == JFileChooser.APPROVE_OPTION) {
                       lujing.setText(chooser.getSelectedFile().getAbsolutePath());
                   }
                 }
           });
      /////////////
      } 
    class mail 
    {
    public mail()throws Exception
    {
    Session session=createSession();
    MimeMessage message=createMessage(session);
            Transport transport=session.getTransport("smtp");


            transport.connect(host,user,pw);
            transport.sendMessage(message,message.getRecipients(Message.RecipientType.TO));
     //transport.close();

    }
    
    public  MimeMessage createMessage(Session session)throws Exception
    {
    MimeMessage message=new MimeMessage(session);
    InternetAddress from1=new InternetAddress("laoziaimenglia@163.com");
    message.setFrom(from1);
        InternetAddress to=new InternetAddress(" 544846384@qq.com");
    message.setRecipient(Message.RecipientType.TO,to);
    
    message.setSubject(subject);
    MimeMultipart multipart=new MimeMultipart("related");
    MimeBodyPart htmlBodyPart=new MimeBodyPart();
    htmlBodyPart.setContent(body,"text/html");
    multipart.addBodyPart(htmlBodyPart);
    MimeBodyPart gifBodyPart=new MimeBodyPart();
    FileDataSource fds=new FileDataSource("h:\\1.jpg");
    gifBodyPart.setDataHandler(new DataHandler(fds));
    gifBodyPart.setContentID("1.jpg");
    MimeBodyPart attach=CreateAttachment(lujing.getText());
    multipart.addBodyPart(attach);
    multipart.addBodyPart(gifBodyPart);
    
    message.setContent(multipart);
    message.saveChanges();

    //MimeBodyPart attachPart=CreateAttachment(lujing.getText()); 
    //allMultipart.addBodyPart(attachPart);
     /*MimeMessage message=new MimeMessage(session);
      InternetAddress from=new InternetAddress("laoziaimenglia@163.com");
            message.setFrom(from);
            InternetAddress to=new InternetAddress("104621235@qq.com");
            message.setRecipient(Message.RecipientType.TO, to);
            message.setSubject(subject);
            message.setText(body);
            message.setSentDate(new Date());
            message.saveChanges();*/

    return message;
    }
    
    
    public MimeBodyPart createContent(String body)throws Exception
    {
    MimeBodyPart contentPart=new MimeBodyPart();
        contentPart.setContent(body,"text/html");
    return contentPart;
    }
    
    public MimeBodyPart CreateAttachment(String lujing)throws Exception


    {
    MimeBodyPart attachPart=new MimeBodyPart();
    FileDataSource fds=new FileDataSource(lujing);
    attachPart.setDataHandler(new DataHandler(fds));
    attachPart.setFileName(fds.getName());
    return attachPart;
    }
    
    public Session createSession()
    {
    Properties props=new Properties();
    props.put("mail.smtp.host", "smtp.163.com");
        props.put("mail.smtp.auth","true");
    Session session=Session.getDefaultInstance(props);
    session.setDebug(true);
    return session;
    }
    
    }  
      
}


public class Email {
    public  static void main(String args[])
   {
    JWF app=new JWF();

    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    app.setSize(720,320);
    app.setVisible(true);
   }
}

[其他解释]
public void sendMessage(Message message,
                        Address[] addresses)
                 throws MessagingException,
                        SendFailedException

    Send the Message to the specified list of addresses.

    If all the addresses succeed the SMTP check using the RCPT TO: command, we attempt to send the message. A TransportEvent of type MESSAGE_DELIVERED is fired indicating the successful submission of a message to the SMTP host.

    If some of the addresses fail the SMTP check, and the mail.stmp.sendpartial property is not set, sending is aborted. The TransportEvent of type MESSAGE_NOT_DELIVERED is fired containing the valid and invalid addresses. The SendFailedException is also thrown.

    If some of the addresses fail the SMTP check, and the mail.stmp.sendpartial property is set to true, the message is sent. The TransportEvent of type MESSAGE_PARTIALLY_DELIVERED is fired containing the valid and invalid addresses. The SMTPSendFailedException is also thrown.

    MessagingException is thrown if the message can't write out an RFC822-compliant stream using its writeTo method. 



看了send message的解释,是没有发出RFC822-compliant stream,不过这只是结果,不知道是什么起因
[其他解释]
该回复于2012-11-16 22:31:46被管理员删除
[其他解释]
这里有SMTPTransport类源码,供查阅:
http://www.jarvana.com/jarvana/view/javax/mail/mail/1.4/mail-1.4-sources.jar!/com/sun/mail/smtp/SMTPTransport.java?format=ok

第566行应该在sendMessage方法内这几句附近:

this.message = (MimeMessage)message;
this.addresses = addresses;
validUnsentAddr = addresses;// until we know better
expandGroups();


很可能是message对象无法强转为MimeMessage类型,那就是传给sendMessage方法的参数message之前为转型好,或未构造为正确类型。
[其他解释]
再此先谢谢dracularking的回复
mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDescription(Part.ATTACHMENT);
mimeBodyPart.setContent(attachment.getBody(), attachment.getContentType()); // 第一个参数是内容, 第二个是类型. text/xml
mimeBodyPart.setFileName(attachment.getName());
mulp.addBodyPart(mimeBodyPart);

设置为text/xml就出现异常了。
[其他解释]
这个我也不太清楚。发Email的项目我也是刚开始做。
I am so sorry.

引用:
楼主  我的邮件发送的时候 错误为 554 DT:SPM查了下说是服务器标记成垃圾右键发送不出去   有没有解决办法源码如下

import javax.swing.JFrame;
import javax.swing.JFileChooser;
import java.awt.Container;
import java.awt.BorderLayout;
……

[其他解释]
引用:
再此先谢谢dracularking的回复
mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDescription(Part.ATTACHMENT);
mimeBodyPart.setContent(attachment.getBody(), attachment.getContentType()); // 第一个参数是内容, 第二个是类型……

一直没时间看,不知道java mail中对于内容类型是怎么规定的,这方面有查过吗
[其他解释]
今天试了几种方法。读文件的时候设置成Base64 位, 可是再发send email 的时候,用Base64解密,后txt and csv 就正常显示了,
可以doc and xls and png 像这样的文件不能正常显示。求解。

引用:
引用:再此先谢谢dracularking的回复
mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDescription(Part.ATTACHMENT);
mimeBodyPart.setContent(attachment.getBody(), attachment……

[其他解释]
看看这个,它的类型貌似是xml的

http://www.openscope.net/2010/07/25/sending-attachments-with-the-javamail-api/


    package com.faceroller.mail;  
      
    public class Mailer {  
          
        private static final Log log = LogFactory.getLog(Mailer.class);  
      
        public static void send(Email email)  
                throws MessagingException, NamingException, IOException {  
      
            /** 


             * prefer the jndi lookup in your container, but when debugging 
             * manually setting properties explicitly will do 
             *  
             */  
      
            // InitialContext ictx = new InitialContext();  
            // Session session = (Session) ictx.lookup("java:/Mail");  
      
            Properties props = (Properties) System.getProperties().clone();  
            props.put("mail.transport.protocol", "smtp");  
            props.put("mail.smtp.host", host);  
            props.put("mail.smtp.port", port);  
            props.put("mail.debug", "true");  
      
            /** 
             * create the session and message 
             *  
             */  
            Session session = Session.getInstance(props, null);  
      
            /** 
             * set the message basics 
             *  
             */  
            MimeMessage message = new MimeMessage(session);  
            Message.setFrom(InternetAddress.parse(email.getFrom(), false)[0]);  
            message.setSubject(email.getSubject());  
            message.setRecipients(  
                javax.mail.Message.RecipientType.TO,  
                InternetAddress.parse(email.getTo(), false)  
            );  
      
      
            /** 
             * multipart attachments here, part one is the message text,  


             * the other is the actual file. notice the explicit mime type  
             * declarations 
             *  
             */  
            Multipart multiPart = new MimeMultipart();  
      
            MimeBodyPart messageText = new MimeBodyPart();  
            messageText.setContent(email.getBodyAsText(), "text/plain");  
            multiPart.addBodyPart(messageText);  
      
            MimeBodyPart report = new MimeBodyPart();  
            report.setFileName(email.getFileName());  
            report.setContent(email.getAttachmentAsText(), "text/xml");  
            multiPart.addBodyPart(report);  
      
            MimeBodyPart rarAttachment = new MimeBodyPart();  
            FileDataSource rarFile = new FileDataSource("C:/my-file.rar");  
            rarAttachment.setDataHandler(new DataHandler(rarFile));  
            rarAttachment.setFileName(rarFile.getName());  
            multiPart.addBodyPart(rarAttachment);  
      
            /** 
             * set the message's content as the multipart obj 
             */  
            message.setContent(multiPart);  
      
      
            /** 
             * do the actual sending here 
             *  
             */  
            Transport transport = session.getTransport("smtp");  
      
            try {  
      
                transport.connect(username, password);  
                transport.sendMessage(message, message.getAllRecipients());  


      
                log.warn("Email message sent");  
      
            } finally {  
                transport.close();  
            }  
        }  
    }  




[其他解释]
引用:
今天试了几种方法。读文件的时候设置成Base64 位, 可是再发send email 的时候,用Base64解密,后txt and csv 就正常显示了,
可以doc and xls and png 像这样的文件不能正常显示。求解。

引用:引用:再此先谢谢dracularkin……

发好邮件以后,收也是用java程序收的?
[其他解释]
MimeBodyPart rarAttachment = new MimeBodyPart();  
            FileDataSource rarFile = new FileDataSource("C:/my-file.rar");  
            rarAttachment.setDataHandler(new DataHandler(rarFile));  
            rarAttachment.setFileName(rarFile.getName());  
           主要是这块,我读出来的内容应该是Base64加密后的。
            rarAttachment.setContent(str) // str 应该是Base64加密的,因为我用Base64解密txt or xml 后都可以正常显示,可是doc or png or xls 就是乱码了。
            multiPart.addBodyPart(rarAttachment);  
[其他解释]
MimeBodyPart report = new MimeBodyPart();  
report.setFileName(email.getFileName());  
report.setContent(email.getAttachmentAsText(), "text/xml");  
multiPart.addBodyPart(report); 

你是说把email.getAttachmentAsText()得到的这段字符串以Base64解密有乱码是吧?我觉得可以理解,doc and xls and png本身就不像txt or xml是文本型的,这是它们最大的区别,可能是内容展现方式不一样

p.s.为什么要这样解密呢?
[其他解释]
引用:
MimeBodyPart report = new MimeBodyPart();  
report.setFileName(email.getFileName());  
report.setContent(email.getAttachmentAsText(), "text/xml");  
multiPart.addBodyPart(report); 

……


这是因为从服务器上读出来的时候就是Base64加密的。
[其他解释]
引用:
这是因为从服务器上读出来的时候就是Base64加密的。

是收邮件打开邮件附件时,对附件内容进行解密?

即使是程序收附件,这些应该都是java mail封状的内部细节,不清楚你(使用者)为什么会涉及到
[其他解释]
引用:
引用:这是因为从服务器上读出来的时候就是Base64加密的。
是收邮件打开邮件附件时,对附件内容进行解密?

即使是程序收附件,这些应该都是java mail封状的内部细节,不清楚你(使用者)为什么会涉及到


可能是我没有说清楚, 是这样的,我的目的是发邮件,可是发邮件的内容和附件是从服务器上读出来的。再读出来后(我怀疑在读完后文件被加密了)再发邮件。
------其他解决方案--------------------


非常抱歉, 读文件的是一个jar,我仅仅调用了一下,它在服务器上的类型是Base64.

[其他解释]
那你这第二个问题和java mail没本质关系了,相当于是独立的一个问题(我以为有关系)

等于是从网络去读取一个附件文件流是吧,你把相关代码发一下最好
[其他解释]
Thanks again.

目前我是这样解决的。关于 text/xml and text/txt 类型的用Base64.decode(String) 方法,其它的用Base64.decodeBuffer(String) 。现在这些文件都正常了。不过还有很多不同格式的文件还没有测试。

再有一个问题:
transport.connect("email-smtp.us-east-1.amazonaws.com", emailUser, emailPassword);
执行到这儿,就不走了,也没有出现异常。 我觉得是connect方法里面出现了问题。
我加了一条session.setDebug(true);
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "email-smtp.us-east-1.amazonaws.com", port 25, isSSL false


引用:
对于doc or png or xls这些类型的文件,是不是要以文件的形式从服务端读出?

最终在邮件程序中应该类型这样用的吧?

Java code?1234MimeBodyPart rarAttachment = new MimeBodyPart();               FileDataSource rarFile = new FileDataSou……

[其他解释]
对于doc or png or xls这些类型的文件,是不是要以文件的形式从服务端读出?

最终在邮件程序中应该类型这样用的吧?


MimeBodyPart rarAttachment = new MimeBodyPart();               
FileDataSource rarFile = new FileDataSource("C:/my-file.rar");               rarAttachment.setDataHandler(new DataHandler(rarFile));               rarAttachment.setFileName(rarFile.getName());              
multiPart.addBodyPart(rarAttachment);  
 
[其他解释]
我去掉了ThreadPool 结果就出来了,原来是线程池的问题:
应该是线程没有执行完,被终结了。

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 200, 50,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());

for(SObject contact : result.getContacts()) {
threadPool.execute(new SendEmail(connection, result.getSender(), result.getEmailTemplate(), contact, result.getAttachments(), result.getDocuments()));
线程中执行的时间可能会比较长。
Thread.sleep(produceTaskSleepTime);
}
threadPool.shutdown();

引用:
Thanks again.

目前我是这样解决的。关于 text/xml and text/txt 类型的用Base64.decode(String) 方法,其它的用Base64.decodeBuffer(String) 。现在这些文件都正常了。不过还有很多不同格式的文件还没有测试。

再有一个问题:
transport.connect("email-smtp.……

[其他解释]
这个发送 xml到没试过。 一般是发送图片 和 txt  doc等。
[其他解释]
不觉得奇怪吗 decode和decodeBuffer应该在编码这个问题上没什么区别吧

decodeBuffer貌似只是将流的内容解码进Buffer里而已
------其他解决方案--------------------


Hi dracularking,

最新情况:

for(SObject contact : contacts) {
Thread thread = new Thread(new SendMessageRunnable(transport, msg, sender, emailTemplate, contact, attachments, documents));
thread.start();
listThread.add(thread);
}

之前是在transport.connect("email-smtp.us-east-1.amazonaws.com", emailUser, emailPassword); 停止的,后来我把这句加到了循环外。现在执行到transport.sendMessage(msg, msg.getAllRecipients()); 就停止了。单线程是没有问题的。

Thanks a lot.
[其他解释]
不错,如果一个sendMessage 出错的话,其它的还是可以继续执行。不过如果 connect 断开的话。程序就停止了。

我想让主线程停止,马上返回一个变量,说程序正在Running.., 可是我把主线程return 后。其它子线程也不跑了。这是为什么?主线程不是不影响其它线程吗?
[其他解释]
引用:
之前是在transport.connect("email-smtp.us-east-1.amazonaws.com", emailUser, emailPassword); 停止的,后来我把这句加到了循环外。现在执行到transport.sendMessage(msg, msg.getAllRecipients()); 就停止了。单线程是没有问题的。

sendMessage方法是同步的,但是多线程同时调用的话,应该会进入排队机制啊,会一直没反应吗?

public synchronized void sendMessage(Message message, Address[] addresses)
    throws MessagingException, SendFailedException {


[其他解释]
引用:
引用:不错,如果一个sendMessage 出错的话,其它的还是可以继续执行。不过如果 connect 断开的话。程序就停止了。

我想让主线程停止,马上返回一个变量,说程序正在Running.., 可是我把主线程return 后。其它子线程也不跑了。这是为什么?主线程不是不影响其它线程吗?
其他子线程也都不跑了是指整……


已经解决了。原来在junit 中跑程序会中断的。具体原因,现在我还不知道。这个贴子我会马上结贴。
dracularking, thanks a lot.
[其他解释]
引用:
不错,如果一个sendMessage 出错的话,其它的还是可以继续执行。不过如果 connect 断开的话。程序就停止了。

我想让主线程停止,马上返回一个变量,说程序正在Running.., 可是我把主线程return 后。其它子线程也不跑了。这是为什么?主线程不是不影响其它线程吗?

其他子线程也都不跑了是指整个程序都中断了吗?

不是的话,比如卡住的话,肯定有什么也许你没提及的原因影响它们运行

是的话,也许你这些子线程都是低级别的比如守护线程。
[其他解释]
引用:
已经解决了。原来在junit 中跑程序会中断的。具体原因,现在我还不知道。这个贴子我会马上结贴。
dracularking, thanks a lot. 


junit啊?我不知道你具体怎么操作的,至少按单元操作,结束了可能就会都中断吧

热点排行