我之前用Javamail写了发送邮件的类,我用的是mail.jar1.4和activation1.1,因为客户的服务器集成的jar包用的是mail.jar1.3,所以现在出现了下面的问题。
1.异常捕获
} catch (SendFailedException e) {
MessagingException sfe = (MessagingException) e;
Exception ne;
while (((ne = sfe.getNextException()) != null) && (ne instanceof MessagingException)) {
sfe = (MessagingException) ne;
if (sfe instanceof SMTPAddressFailedException) {
SMTPAddressFailedException ssfe = (SMTPAddressFailedException) sfe;
exAddress = ssfe.getAddress().toString()+",";
exAddress1 = exAddress1 + exAddress;
}
}
exAddress1 = exAddress1.trim().substring(0, exAddress1.length()-1);
上面代码的意思是捕获出不能发送的邮箱地址,其中的SMTPAddressFailedException类在mail包中com\sun\mail\smtp,但是在1.3版本下相应的包下没有这个SMTPAddressFailedException类,而SendFailedException异常中无法取得不合法地址,本想通过SendFailedException.getInvalidAddresses() 来取得这些地址,但是没有实现,因为他返回的Address[]类型,在转化的时候出现了问题。
2.发送附件
//datasource 是我从数据库中取出来的附件的内容,类型BLOB,下面的代码在for循环内,因为之前可能取出来了多个附件
datasource = sendAtchInfo.get(i).getTb08SendAtchFile().getAtchFileEnt();
if(datasource !=null){
//取得附件的名
fileName = sendAtchInfo.get(i).getTb08SendAtchFile().getAtchFileNm();
//取得附件的类型,比如image/jpeg,text/plain,application/zip等类型
type = sendAtchInfo.get(i).getTb08SendAtchFile().getRendType();
//下面就是处理的操作
ds = new ByteArrayDataSource(datasource,type);
dataHandler = new DataHandler(ds);
mBodyPart = new MimeBodyPart();
mBodyPart.setDataHandler(dataHandler);
mBodyPart.setFileName(MimeUtility.encodeText(fileName,mailEncoding,null));
mPart.addBodyPart(mBodyPart);
}
实行完之后放到了结构体MimeMessage中(MimeMessage.setContent(mPart)),但是换成1.3之后,大家可以发现ByteArrayDataSource不存在了,在1.4的位置是mail\javax\mail\util中,但是在1.3中相应位置,没有util这个包,我之前用过下面的方法:
//ds = new ByteArrayDataSource(datasource,type);
//dataHandler = new DataHandler(ds);
//mBodyPart = new MimeBodyPart();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(datasource);
mBodyPart = new MimeBodyPart(byteArrayInputStream);
mBodyPart.setHeader("Content-Type", type);
//mBodyPart.setDataHandler(dataHandler);
mBodyPart.setFileName(MimeUtility.encodeText(fileName,mailEncoding,null));
mPart.addBodyPart(mBodyPart);
}
这样做的目的就是用MimeBodyPart(InputStream)和setHeader方法代替ByteArrayDataSource(InputStream,String),但是这样总是会出现IO异常,而且发送不成功,但是我调试的时候,确实是把文件内容以byte[]型放进去了。
希望得到大家的指点。谢谢。
1.异常捕获
} catch (SendFailedException e) {
MessagingException sfe = (MessagingException) e;
Exception ne;
while (((ne = sfe.getNextException()) != null) && (ne instanceof MessagingException)) {
sfe = (MessagingException) ne;
if (sfe instanceof SMTPAddressFailedException) {
SMTPAddressFailedException ssfe = (SMTPAddressFailedException) sfe;
exAddress = ssfe.getAddress().toString()+",";
exAddress1 = exAddress1 + exAddress;
}
}
exAddress1 = exAddress1.trim().substring(0, exAddress1.length()-1);
上面代码的意思是捕获出不能发送的邮箱地址,其中的SMTPAddressFailedException类在mail包中com\sun\mail\smtp,但是在1.3版本下相应的包下没有这个SMTPAddressFailedException类,而SendFailedException异常中无法取得不合法地址,本想通过SendFailedException.getInvalidAddresses() 来取得这些地址,但是没有实现,因为他返回的Address[]类型,在转化的时候出现了问题。
2.发送附件
//datasource 是我从数据库中取出来的附件的内容,类型BLOB,下面的代码在for循环内,因为之前可能取出来了多个附件
datasource = sendAtchInfo.get(i).getTb08SendAtchFile().getAtchFileEnt();
if(datasource !=null){
//取得附件的名
fileName = sendAtchInfo.get(i).getTb08SendAtchFile().getAtchFileNm();
//取得附件的类型,比如image/jpeg,text/plain,application/zip等类型
type = sendAtchInfo.get(i).getTb08SendAtchFile().getRendType();
//下面就是处理的操作
ds = new ByteArrayDataSource(datasource,type);
dataHandler = new DataHandler(ds);
mBodyPart = new MimeBodyPart();
mBodyPart.setDataHandler(dataHandler);
mBodyPart.setFileName(MimeUtility.encodeText(fileName,mailEncoding,null));
mPart.addBodyPart(mBodyPart);
}
实行完之后放到了结构体MimeMessage中(MimeMessage.setContent(mPart)),但是换成1.3之后,大家可以发现ByteArrayDataSource不存在了,在1.4的位置是mail\javax\mail\util中,但是在1.3中相应位置,没有util这个包,我之前用过下面的方法:
//ds = new ByteArrayDataSource(datasource,type);
//dataHandler = new DataHandler(ds);
//mBodyPart = new MimeBodyPart();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(datasource);
mBodyPart = new MimeBodyPart(byteArrayInputStream);
mBodyPart.setHeader("Content-Type", type);
//mBodyPart.setDataHandler(dataHandler);
mBodyPart.setFileName(MimeUtility.encodeText(fileName,mailEncoding,null));
mPart.addBodyPart(mBodyPart);
}
这样做的目的就是用MimeBodyPart(InputStream)和setHeader方法代替ByteArrayDataSource(InputStream,String),但是这样总是会出现IO异常,而且发送不成功,但是我调试的时候,确实是把文件内容以byte[]型放进去了。
希望得到大家的指点。谢谢。
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/msword
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:841)
at javax.activation.DataHandler.writeTo(DataHandler.java:295)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1147)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:668)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:233)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:67)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:839)
at javax.activation.DataHandler.writeTo(DataHandler.java:295)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1147)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1612)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:422)
at javax.mail.Transport.send0(Transport.java:163)
at javax.mail.Transport.send(Transport.java:80)
at jp.co.hitachi.jkk.bunsho.bb.common.online.BBCCMailSend.sendMail(BBCCMailSend.java:92)
at jp.co.hitachi.jkk.bunsho.bb.player.handler.BBSDocShoriKianHassouSetHassouHandler.executeUOC(BBSDocShoriKianHassouSetHassouHandler.java:844)
at jp.co.hitachi.itg.ecando.pstruts.PsHandler.processExecuteUOC(PsHandler.java)
at jp.co.hitachi.itg.ecando.pstruts.PsHandler.exec(PsHandler.java)
at jp.co.hitachi.itg.ecando.pstruts.PsEventHandler.exec(PsEventHandler.java)
at jp.co.hitachi.itg.ecando.pstruts.PsHandler.execute(PsHandler.java)
at jp.co.hitachi.jkk.bunsho.bb.player.action.BBSDocShoriKianHassouSetEventAction.executeHandler(BBSDocShoriKianHassouSetEventAction.java:70)
at jp.co.hitachi.itg.ecando.pstruts.PsAction.processExecuteHandler(PsAction.java)
at jp.co.hitachi.itg.ecando.pstruts.PsAction.exec(PsAction.java)
at jp.co.hitachi.itg.ecando.pstruts.PsEventAction.exec(PsEventAction.java)
at jp.co.hitachi.itg.ecando.pstruts.PsAction.execute(PsAction.java)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at jp.co.hitachi.itg.ecando.pstruts.PsActionServlet.service(PsActionServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at jp.co.hitachi.jkk.bunsho.bb.common.online.BBCCLoginCheckFilter.doFilter(BBCCLoginCheckFilter.java:84)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*; public class AttachExample {
public static void main (String args[])
throws Exception {
String host = args[0];
String from = args[1];
String to = args[2];
String fileAttachment = args[3];
// Get system properties
Properties props = System.getProperties();
// Setup mail server
props.put("mail.smtp.host", host);
// Get session
Session session =
Session.getInstance(props, null);
// Define message
MimeMessage message =
new MimeMessage(session);
message.setFrom(
new InternetAddress(from));
message.addRecipient(
Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject(
"Hello JavaMail Attachment");
// create the message part
MimeBodyPart messageBodyPart =
new MimeBodyPart();
//fill message
messageBodyPart.setText("Hi");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
DataSource source =
new FileDataSource(fileAttachment);
messageBodyPart.setDataHandler(
new DataHandler(source));
messageBodyPart.setFileName(fileAttachment);
multipart.addBodyPart(messageBodyPart);
// Put parts in message
message.setContent(multipart);
// Send the message
Transport.send( message );
}
}
看看吧,好像是要用到Multipart multipart = new MimeMultipart();吧。
看看吧,好像是要用到Multipart multipart = new MimeMultipart();吧。这个我肯定加上了。
真郁闷,真的没有办法了。问题接二连三。
我现在是不能用,因为我是从数据库中取出来的byte【】型的数据,现在的问题是怎么能将这个byte【】型转化成DataSource,从而能放到MimeBodyPart中,setContent(Object,String)这个不行,总是出现java.io.IOException: "text/plain" DataContentHandler requires String object, was given object of type class [B
或者javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/vnd.ms-excel 这样的异常,两个异常上面是我发送的文本文件做为附件,下面的异常是我发送的excel的附件。
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(datasource);
mBodyPart = new MimeBodyPart(byteArrayInputStream);
的时候,text/plain这样类型的附件是可以正常发送的,但是其他的类型就全然不能发送了。异常:
java.io.IOException: Error in encoded stream, got 2
at com.sun.mail.util.BASE64DecoderStream.decode(BASE64DecoderStream.java:148)
at com.sun.mail.util.BASE64DecoderStream.read(BASE64DecoderStream.java:53)
at com.sun.mail.util.BASE64DecoderStream.read(BASE64DecoderStream.java:78)
at java.io.FilterInputStream.read(Unknown Source)
.......
如果这样处理:
mBodyPart = new MimeBodyPart();
mBodyPart.setDataHandler(new DataHandler(datasource,type));
的时候,text/plain类型的下面的异常
"text/plain" DataContentHandler requires String object, was given object of type class [B
at com.sun.mail.handlers.text_plain.writeTo(text_plain.java:103)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:839)
at javax.activation.DataHandler.writeTo(DataHandler.java:295)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1147)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:668)
其他类型的就是
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/vnd.ms-excel
红色部分就是相应的异常。
还在解决中,希望熟悉javamail的高手们提意见。
是因为dataHandler中找对应的文件mailcap中没有找到你设置的类型所以dch=null
采用setContent(Object,value)需要setCommandMap,setDataContentHandlerFactory设置的支持,目前不清楚如何解决换一种思路
创建
private boolean creatMailBodyPartToFile(byte[] bytes,String fileName){
boolean bl = false;
try
{
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
try {
fileOutputStream.write(bytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(FileNotFoundException e)
{
bl = false;
RuntimeException re = new RuntimeException((new StringBuilder())
.append("Failed in opening specified file. FileName=")
.append(fileName).toString());
re.initCause(e);
throw re;
}
}删除
private boolean deleteMailBodyPartFile(String fileName){}ds = new FileDataSource(file);
mBodyPart = new MimeBodyPart();
dataHandler = new DataHandler(ds);
mBodyPart.setDataHandler(dataHandler);
此方法虽然不是最佳,不过还是可以的。
我之前也想用这种办法,就是把byte转成文件,正在测试中,如果没有问题,就给分。
lanlanq兄,既然能想出这个办法,就顺便给我看看为什么一定要用DataSource,为什么不能用Object,不能放在content里来进行操作呢?