2009-03-01 15 views
0

私はJava Mailとそのストリームでどのように動作するかについて質問します。 Java Mail 1.4.1にはMimeMessage constructor that accepts a streamがあります。私の理解は、私はこのコンストラクタにストリームを渡すことができ、それは私のためにMimeMessageにそれを解析することです。私はこれを証明するために2つのテストを書いた。最初のテストは、部分的な複数部分MIMEメッセージのみを含むストリームを送信します。 2番目のテストでは、2つの完全なマルチパートMIMEメッセージを含むストリームを送信します。どちらも私が期待した通りに動作しません。最初のものは例外をスローしません。もう1つはストリーム全体を何らかの形で1つのメッセージに読み込みます。これはJava Mailのバグですか、間違った種類のストリームを使用していますか?あるいは私はもっと大きなものを逃していますか?JavaMail質問またはバグ?

それは少し長いですが、ここではテストコードです:

import java.io.BufferedInputStream; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Properties; 

import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.mail.BodyPart; 
import javax.mail.MessagingException; 
import javax.mail.Multipart; 
import javax.mail.Session; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeMultipart; 
import javax.mail.util.ByteArrayDataSource; 

import junit.framework.TestCase; 


public class mimeTest extends TestCase { 

    public void testPartialMulitpartMessage() throws MessagingException, IOException 
    { 
     Properties props = new Properties(); 
     Session session = Session.getInstance(props, null); 
     String testMsg1 = "test"; 
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

     // Step 1 - Create first MIME message 
     MimeMessage mesg = new MimeMessage(session); 
     Multipart mp = new MimeMultipart("mixed"); 
     //create a child part 
     BodyPart bodyPart = new MimeBodyPart(); 
     bodyPart.setContent(testMsg1, "application/x-special"); 
     bodyPart.setHeader("Content-Length", String.valueOf(testMsg1.length())); 
     DataSource ds = new ByteArrayDataSource(testMsg1, "application/x-special"); 
     bodyPart.setDataHandler(new DataHandler(ds)); 
     bodyPart.setHeader("Content-Transfer-Encoding", "8bit"); 
     // Add the child part to the multipart 
     mp.addBodyPart(bodyPart); 
     // Put the MultiPart into the Message 
     mesg.setContent(mp); 

     // Step 2 - write to a stream 
     mesg.writeTo(byteArrayOutputStream); 

     byte bytes[] = byteArrayOutputStream.toByteArray(); 
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes, 0, 10); 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(byteArrayInputStream); 
     boolean thrown = false; 
     try 
     { 
      //Why does this not throw a messageexception. 
      MimeMessage mesg2 = new MimeMessage(session, bufferedInputStream); 
     } 
     catch(MessagingException me){ 
      thrown = true; 
     } 

     if(!thrown) { 
      assertTrue("Expected exception not thrown.", false); 
     } 
    } 

    public void testMulitpleMulitpartMessages() throws MessagingException, IOException { 
     Properties props = new Properties(); 
     Session session = Session.getInstance(props, null); 
     String testMsg1 = "test"; 
     String testMsg2 = "test1"; 
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

     // Step 1 - Create first MIME message 
     MimeMessage mesg = new MimeMessage(session); 
     Multipart mp = new MimeMultipart("mixed"); 
     //create a child part 
     BodyPart bodyPart = new MimeBodyPart(); 
     bodyPart.setContent(testMsg1, "application/x-special"); 
     bodyPart.setHeader("Content-Length", String.valueOf(testMsg1.length())); 
     DataSource ds = new ByteArrayDataSource(testMsg1, "application/x-special"); 
     bodyPart.setDataHandler(new DataHandler(ds)); 
     bodyPart.setHeader("Content-Transfer-Encoding", "8bit"); 
     // Add the child part to the multipart 
     mp.addBodyPart(bodyPart); 
     // Put the MultiPart into the Message 
     mesg.setContent(mp); 

     // Step 2 - write to a stream 
     mesg.writeTo(byteArrayOutputStream); 

     // Step 3 - Create second MIME message 
     MimeMessage mesg2 = new MimeMessage(session); 
     mp = new MimeMultipart("mixed"); 
     //create a child part 
     bodyPart = new MimeBodyPart(); 
     bodyPart.setContent(testMsg2, "application/x-special"); 
     bodyPart.setHeader("Content-Length", String.valueOf(testMsg2.length())); 
     ds = new ByteArrayDataSource(testMsg2, "application/x-special"); 
     bodyPart.setDataHandler(new DataHandler(ds)); 
     bodyPart.setHeader("Content-Transfer-Encoding", "8bit"); 
     // Add the child part to the multipart 
     mp.addBodyPart(bodyPart); 
     // Put the MultiPart into the Message 
     mesg2.setContent(mp); 

     // Step 4 - write to the same stream 
     mesg2.writeTo(byteArrayOutputStream); 

     // Step 6 - read the two messages back 
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(byteArrayInputStream); 
     List<MimeMessage> listMessages = new ArrayList<MimeMessage>(); 
     while (bufferedInputStream.available() > 0) { 
      //http://java.sun.com/products/javamail/javadocs/javax/mail/internet/MimeMessage.html#MimeMessage(javax.mail.Session,%20java.io.InputStream) 
      //The InputStream will be left positioned at the end of the data for the message. 
      //WHY does this not work? It reads the whole stream. 
      mesg = new MimeMessage(session, bufferedInputStream); 
      //output the message 
      listMessages.add(mesg); 
     } 

     assertEquals(2, listMessages.size()); 

     assertTrue(listMessages.get(0).equals(mesg)); 
     assertTrue(listMessages.get(1).equals(mesg2)); 
    } 
} 

答えて

4

のJavaMail APIは「豚であり、それはあなたのように動作していないため、生のそれを使用して大規模で、報われない作業です期待しています。

SpringのAPIレイヤーを使用することをお勧めします。ストレスの少ないものです。それはJavaMailを完全に隠すわけではなく、予測しやすく、テストにやさしいだけです。

1

JavaMailはストリーム全体を読み込み、おそらくバッファリングします。私は@skaffmanに同意しますが、私の見解は、それがなぜならコメントがなくてもひどく最適化されていて、それが使いにくいということです。

MimeMessage.parse(InputStream)メソッドは、あなたが処理しているものです。あなたがSharedInputStreamを使用していない限り、ストリームを閉じずにストリーム全体を読み込みます。これは、あなたが見ているように、InputStreamを最後に置いたままにします。

MimeMessageはストリーム内のデータを解釈することはあまりありません。したがって、あなたの言葉を使用するには、「もっと大きなものがない」と思います。なぜあなたはそれがデータを解釈することを期待していますか?ストリームの作成に使用しているマルチパートメッセージを送信できますか?