2011-08-19 102 views
0

首先,我想感谢大家的答案posted.This网站是伟大的。 其次,我有一个问题,经过几天的搜索,我仍然无法弄清楚。我发现很多人有同样的问题,但没有答案。 我正尝试将图像上载到在应用程序引擎上运行的应用程序,并以附件形式发送包含该图像的电子邮件。我也使用org.apache.commons.fileupload来上传图片。 我成功发送了电子邮件,但我遇到了附件问题。 我的HTML形式如下:问题发送电子邮件与图像附件从应用程序引擎使用Java邮件API

<form id="contact" action="/sign" method="post" enctype="multipart/form-data"> 
          <fieldset> 
           <label>Nume/Prenume</label> 
           <input type="text" name="nume" /> 
           <label>Telefon</label> 
           <input type="text" name="telefon" /> 
           <label>E-mail</label> 
           <input type="text" name="email"/>          
          </fieldset> 
          <fieldset> 
           <label>Textul sesizarii</label> 
           <textarea name="textulses"></textarea> 
           <div class="upload-fix-wrap"> 
            <input size="35" class="upload" type="file"   name=myFile /> 
            <input type="text" /> 
            <button>Incarca poze</button> 
           </div> 
           <button class="send" type="submit">Trimite </button> 
          </fieldset> 
         </form> 

我的web.xml文件中,我选择的servlet至极应该回答这个样子的:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> 
<servlet> 
    <servlet-name>sign</servlet-name> 
    <servlet-class>com.campiacareiului.CampiaCareiuluiServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>sign</servlet-name> 
    <url-pattern>/sign</url-pattern> 
</servlet-mapping> 
<welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
</welcome-file-list> 
</web-app> 

所以,现在我有一个html表单和一个servlet回复。 首先,我试图通过使用javax.mail:

public class CampiaCareiuluiServlet extends HttpServlet { 
private String nume=null; 
private String telefon=null; 
private String email=null; 
private String textulses=null; 
private String attname=null; 
private byte[] buffer = new byte[8192000]; 
private boolean att=false; 
private int size=0; 
private static final Logger log = 
      Logger.getLogger(CampiaCareiuluiServlet.class.getName()); 
public void doPost(HttpServletRequest req, HttpServletResponse resp) 
     throws IOException { 
    try { 

     ServletFileUpload upload=new ServletFileUpload(); 
     FileItemIterator it = upload.getItemIterator(req); 
     while(it.hasNext()){ 
      FileItemStream item = it.next(); 
      String name = item.getFieldName(); 
      InputStream stream = item.openStream(); 
      if (item.isFormField()) { 
    if(name.equals("nume")) nume=Streams.asString(stream); 
     else if(name.equals("telefon")) telefon=Streams.asString(stream); 
     else if(name.equals("email")) email=Streams.asString(stream); 
     else if(name.equals("textulses")) textulses=Streams.asString(stream); 
      } else { 
       att=true; 
       attname=item.getName(); 

       int len; 
       size=0; 
       while ((len = stream.read(buffer, 0, buffer.length)) != -1){ 
        size+=len; 

       } 

      } 

     } 
      Properties props = new Properties(); 
      Session session = Session.getDefaultInstance(props, null); 

    String msgBody = "Nume/Prenume: "+nume+" Telefon: "+telefon+" Mail:"+email+"Textul Sesizarii: "+textulses; 
    Message msg = new MimeMessage(session); 
       msg.setFrom(new  InternetAddress("[email protected]", "")); 
       msg.addRecipient(Message.RecipientType.TO, 
           new InternetAddress("[email protected]", "Mr. User")); 
       msg.setSubject("Mail Sesizare Campia Careiului"); 
       msg.setText(msgBody); 
    if(att){ 
     byte[] bufferTemp = new byte[size]; 
     for(int i=0;i<=size;i++) 
      bufferTemp[i]=buffer[i]; 
      Multipart mp=new MimeMultipart(); 
        MimeBodyPart attachment= new MimeBodyPart(); 

        DataSource src = new ByteArrayDataSource 
          (bufferTemp,"image/jpeg"); 
        attachment.setFileName(attname); 
        attachment.setContent(src,"image/jpeg"); 
        mp.addBodyPart(attachment); 
        msg.setContent(mp); 

     } 
    Transport.send(msg); 
    resp.sendRedirect("/contact.html"); 
    } catch (Exception ex) { 
      try { 
      throw new ServletException(ex); 
     } catch (ServletException e) { 

      e.printStackTrace(); 
} 
     } 

} 
} 

当我调试它表明它已上传的图像缓冲区中的应用,但它未能发送邮件(无异常被抛出)(我将应用程序上传到应用程序引擎,因为如果您在本地运行应用程序,则无法发送电子邮件)。 接下来我尝试使用低级别的API。我所做的改变是:

    Properties props = new Properties(); 
      Session session = Session.getDefaultInstance(props, null); 

      String msgBody = "Nume/Prenume: "+nume+" Telefon: "+telefon+" Mail: "+email+" Textul Sesizarii: "+textulses; 

      MailService service = MailServiceFactory.getMailService(); 
      MailService.Message msg = new MailService.Message(); 
        msg.setSender("[email protected]"); 
        msg.setTo("[email protected]"); 
        msg.setSubject("Mail Sesizare Campia Careiului"); 
        msg.setTextBody(msgBody); 
    if(att){ 
     byte[] bufferTemp = new byte[size]; 
     for(int i=0;i<=size;i++) 
      bufferTemp[i]=buffer[i]; 

      MailService.Attachment attachment=new MailService.Attachment("picture.pdf", 
        bufferTemp); 
      msg.setAttachments(attachment); 
      } 
      service.send(msg); 
          resp.sendRedirect("/contact.html"); 

现在,它发出的电子邮件,附件,但是当我尝试下载从我的电子邮件帐户的附件(PDF或一个图片)它不承认它它只是说该文件可能已损坏。当我试图发送一个图像时,我会放入“image/jpeg”,当我试图发送PDF时,我会放入“application/pdf”。 我到处搜索,我发现其他人有这个问题,但没有解决方案。如果有人能帮助我,我会很感激。 (我为我的拼写错误道歉) 我进口:

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Iterator; 
import java.util.Properties; 
import java.util.logging.Logger; 
import javax.servlet.ServletException; 
import javax.activation.DataSource; 
import javax.mail.Message; 
import javax.mail.MessagingException; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.AddressException; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMultipart; 
import javax.mail.util.ByteArrayDataSource; 
import javax.mail.Multipart; 
import javax.servlet.http.*; 
import org.apache.commons.fileupload.FileItem; 
import org.apache.commons.fileupload.FileItemFactory; 
import org.apache.commons.fileupload.FileItemStream; 
import org.apache.commons.fileupload.FileItemIterator; 
import org.apache.commons.fileupload.FileUploadBase; 
import org.apache.commons.fileupload.FileUploadException; 
import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
import org.apache.commons.fileupload.servlet.ServletFileUpload; 
import org.apache.commons.fileupload.util.Streams; 
import org.apache.commons.io.IOUtils; 

import com.google.appengine.api.mail.MailService; 
import com.google.appengine.api.mail.MailServiceFactory; 

我成功发送的电子邮件与以下code.But我的问题是,当我尝试下载附件,或附件当我尝试查看它时,它说它已损坏,并且不能识别它。我认为问题在于上传图像。要上传图片我使用org.apache.commons.fileupload。 在这里,我的图像上传到一个字节数组:

while ((len = stream.read(buffer, 0, buffer.length)) != -1) 
      { 
       size+=len; 
      } 

我还跟踪上载的图像的尺寸在“大小” 在这里,我在apropriate尺寸的另一个缓冲器移动图像:

  byte[] bufferTemp = new byte[size]; 
      for(int i=0;i<size;i++) 
       bufferTemp[i]=buffer[i]; 

附件中的图像与上传的图像尺寸相同,但以某种方式损坏。如果任何人都可以提供帮助。源代码是:

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 
import java.util.logging.Logger; 
import javax.servlet.ServletException; 
import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.mail.Message; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMultipart; 
import javax.mail.util.ByteArrayDataSource; 
import javax.mail.Multipart; 
import javax.servlet.http.*; 

import org.apache.commons.fileupload.FileItemStream; 
import org.apache.commons.fileupload.FileItemIterator; 
import org.apache.commons.fileupload.servlet.ServletFileUpload; 
import org.apache.commons.fileupload.util.Streams; 


@SuppressWarnings("serial") 
public class CampiaCareiuluiServlet extends HttpServlet { 
private String nume=null; 
private String telefon=null; 
private String email=null; 
private String textulses=null; 
private String attname=null; 
private byte[] buffer = new byte[8192000]; 
private boolean att=false; 
private int size=0; 
private static final Logger log = 
     Logger.getLogger(CampiaCareiuluiServlet.class.getName()); 
public void doPost(HttpServletRequest req, HttpServletResponse resp) 
     throws IOException { 
    try { 

     ServletFileUpload upload=new ServletFileUpload(); 
     FileItemIterator it = upload.getItemIterator(req); 
     while(it.hasNext()){ 
      FileItemStream item = it.next(); 
      String name = item.getFieldName(); 
      InputStream stream = item.openStream(); 
      if (item.isFormField()) { 
       if(name.equals("nume")) nume=Streams.asString(stream); 
       else if(name.equals("telefon")) telefon=Streams.asString(stream); 
       else if(name.equals("email")) email=Streams.asString(stream); 
       else if(name.equals("textulses")) textulses=Streams.asString(stream); 
      } else { 
       att=true; 
       attname=item.getName(); 

       int len; 
       size=0; 
       while ((len = stream.read(buffer, 0, buffer.length)) != -1){ 
        size+=len; 

       } 

      } 

     } 
     Properties props = new Properties(); 
     Session session = Session.getDefaultInstance(props, null); 

     String msgBody = "Nume/Prenume: "+nume+" Telefon: "+telefon+" Mail: "+email+" Textul Sesizarii: "+textulses; 

     Message msg = new MimeMessage(session); 
     msg.setFrom(new InternetAddress("[email protected]", "gmail.com Adrian Ursu")); 
     msg.addRecipient(Message.RecipientType.TO, 
       new InternetAddress("[email protected]", "Mr. User")); 
     msg.setSubject("Mail Sesizare Campia Careiului"); 

     if(!att){ 
      msg.setText(msgBody);  
     } 
     else{ 
      byte[] bufferTemp = new byte[size]; 
      for(int i=0;i<size;i++) 
       bufferTemp[i]=buffer[i]; 

      Multipart mp=new MimeMultipart(); 

      MimeBodyPart textPart = new MimeBodyPart(); 
      textPart.setContent(msgBody, "text/plain"); 

      mp.addBodyPart(textPart); 

      MimeBodyPart attachment= new MimeBodyPart(); 
      DataSource src = new ByteArrayDataSource 
        (bufferTemp, "image/jpeg"); 
      attachment.setFileName(attname);  
      attachment.setDataHandler(new DataHandler 
        (src)); 
      mp.addBodyPart(attachment); 
      msg.setContent(mp); 
      msg.saveChanges(); 



     } 
     Transport.send(msg); 

     resp.sendRedirect("/contact.html"); 
    } catch (Exception ex) { 
     try { 
      throw new ServletException(ex); 
     } catch (ServletException e) { 

      e.printStackTrace(); 
     } 
    } 

} 
} 

回答

1

我认为这个问题在例如#1 是要设置一个文本的身体,然后尝试添加多。这是不正确的。消息可以是Content-Type: text/plainContent-Type: multipart/mixed,但不能同时为两者。如果有附件,则需要将文本正文添加为多重部分之一。像这样的(未经测试)的东西:

if (!att) { 
     msg.setText(msgBody); 
    } else { 

     //first build and add the text part 
     MimeBodyPart textPart = new MimeBodyPart(); 
     textPart.setContent(msgBody, "text/plain"); 

     Multipart mp=new MimeMultipart(); 
     mp.addBodyPart(textPart)); 

     //now read/buffer the image data (?) 
     byte[] bufferTemp = new byte[size]; 
     for(int i=0;i<=size;i++) 
      bufferTemp[i]=buffer[i]; 
      // YOU NEED TO FIX THIS!! 
     } 

     // now add the attachment part. 
     // the attachment data must be added all together, not in pieces 
     MimeBodyPart attachment= new MimeBodyPart(); 

     // YOU NEED TO FIX THIS!! 
     attachment.setFileName(attname); 
     attachment.setContent(bufferTemp,"image/jpeg"); 
     mp.addBodyPart(attachment); 
     msg.setContent(mp); 

还拥有你在你的图像数据读取的方式有问题,但你有没有提供了足够的代码为我来告诉你如何纠正它。在将其添加到正文部分内容之前,您需要将整个图像数据读入某个对象(数组,缓冲区等)。并且您不能添加src作为attachment的内容 - 您必须使用实际数据 - 字符串或字节[]等。

要帮助理解身体部位的概念,请尝试和可视化消息。电子邮件标题列出了Content-type: multipart/mixed的标题,封闭部分为Content-type: text/plainContent-type: image/jpeg

To: [email protected] 
From: [email protected] 
Date: Aug 19, 2011 
Content-Type: multipart/mixed; boundary="aswevb323f23f3f" 

This is a message with multiple parts in MIME format. 
--aswevb323f23f3f 
Content-Type: text/plain 

This is the body of the message. 
--aswevb323f23f3f 
Content-Type: image/jpeg 
Content-Transfer-Encoding: base64 

ZQs0bWw+CiAgPGhlYWQ+CiAgP49oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg 
Ym9keSBvZiB0aGUgbWVzc2FnZa48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg== 
--aswevb323f23f3f 
+0

谢谢。我已经尝试过,但仍然无法正常工作。在这里我读取缓冲区中的图像,并且保存大小为read的字节数:while((len = stream.read(buffer,0,buffer.length))!= -1){ \t \t \t \t size + = len;问题是缓冲区的大小是8192000,所以我得到了大小为no的字节,我只是将它移动到另一个缓冲区bufferTemp中。我将附件的内容更改为attachment.setContent(bufferTemp,“image/jpeg”);但它仍然不起作用。 – Berry

+0

它不会发送电子邮件 – Berry

+0

我建议您先验证您是否可以发送“常规”电子邮件,而无需附件。然后尝试使用多部分/混合和一个或两个文本部分创建电子邮件,而不是为了确保您没有发送电子邮件的问题的图像。如果电子邮件有效,请解决图像问题。否则,您需要首先解决基本电子邮件传递的问题。 –

1

我终于搞定了。问题(当然)上传图像。我正在覆盖缓冲区中的相同字节,我没有考虑偏移量。正确的方法是:

 int len=0; 
     size=0; 
     while ((len = stream.read(buffer, size,buffer.length)) != -1) 
       { 
        size+=len; 
       } 
+0

如果您的图片超过8Mb,则此代码仍存在问题。考虑使用['IOUtils#toByteArray()'](http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#toByteArray%28java.io.InputStream%29)。 –

+0

谢谢Mat.I会使用它。 – Berry

+1

IOUtils#toByteArray()就是我所需要的(谢谢dma_k)。我喜欢这个网站 – Berry

相关问题