2012-01-07 31 views
13

Estoy escribiendo una pequeña aplicación de Java utilizando JavaMail que envía al usuario un correo electrónico automático. Pueden elegir entre (por ahora) dos puertos: 25 y 587. El puerto se puede seleccionar mediante un botón de opción en la GUI.Cómo cambiar el puerto de JavaMail

Agregué un botón de prueba para permitir al usuario probar la configuración del correo electrónico (incluido el puerto). Sin embargo, por alguna razón, una vez que el usuario intenta enviar un correo electrónico de prueba, no se puede cambiar el puerto. Javamail siempre usará el puerto del correo electrónico de prueba original.

Ejemplo: el usuario intenta enviar un correo electrónico en el puerto 25 y JavaMail dice que no puede conectarse en el puerto 25 (por ejemplo, el host SMTP usa otro puerto). El usuario hace clic en el puerto 587 e intenta enviar un nuevo correo electrónico. JavaMail arroja un error que dice que no se puede conectar en el puerto 25, nuevamente.

Estoy algo perplejo sobre por qué. Cada vez que se envía un nuevo correo electrónico de prueba, se crea un objeto SendMailUsingAuthentication completamente nuevo. Dentro de esa clase, las propiedades siempre se reinician en el puerto correcto. Cada vez que depuro, hasta donde puedo ver, todas las variables son correctas y están asociadas con el puerto correcto. ¿Hay algo dentro del transporte que me falta?

En la GUI front-end:

private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {           

    int port = port25RadioButton.isSelected() ? PORT_25 : PORT_587; 
    notifier = new SendMailUsingAuthentication(hostNameTextField.getText(), 
      userTextField.getText(), getPassword(), emailTextField.getText().split(","),port); 


    Thread wait = new Thread(new Runnable() { 

     public void run() { 
      try { 
       changeStatusText("Sending test email..."); 
       notifier.postTestMail(); 
       changeStatusText("Test email sent."); 
      } catch (AddressException ex) { 
       changeStatusText("Error. Invalid email address name."); 
      } catch (MessagingException ex) { 
       changeStatusText("SMTP host connection refused."); 
       System.err.println(ex.getMessage()); 
      } catch (Exception ex) { 
       System.err.println(ex); 
      } 
     } 
    }); 

    wait.start(); 
} 

En la clase remitente de correo electrónico:

public void postTestMail() throws MessagingException, AddressException{ 
    String[] testReciever = new String[1]; 
    testReciever[0] = emailList[0]; 
    postMail(testReciever, "Test email.", "Your email settings are successfully set up.", emailFromAddress); 
} 

private void postMail(String recipients[], String subject, 
     String message, String from) throws MessagingException, AddressException { 

    //Set the host smtp address 
    Properties props = new Properties(); 
    props.put("mail.smtp.port", smtpPort); 
    props.put("mail.smtp.host", smtpHostName); 
    props.put("mail.smtp.auth", "true"); 
    props.put("mail.smtp.starttls.enable", true); 
    Authenticator auth = new SMTPAuthenticator(); 
    Session session = Session.getDefaultInstance(props, auth); 
    session.setDebug(false); 

    // create a message 
    Message msg = new MimeMessage(session); 

    // set the from and to address 
    InternetAddress addressFrom = new InternetAddress(from); 
    msg.setFrom(addressFrom); 

    InternetAddress[] addressTo = new InternetAddress[recipients.length]; 
    for (int i = 0; i < recipients.length; i++) { 
     addressTo[i] = new InternetAddress(recipients[i]); 
    } 
    msg.setRecipients(Message.RecipientType.TO, addressTo); 

    // Setting the Subject and Content Type 
    msg.setSubject(subject); 
    msg.setContent(message, "text/plain"); 
    Transport.send(msg); 
} 

Respuesta

22

Esto sucede porque usted está utilizando getDefaultInstance() cuales says:

Obtener el valor por defecto Objeto de sesión Si todavía no se ha configurado un valor predeterminado, se crea e instala un nuevo objeto de sesión como predeterminado.

Y que el argumento Properties se "usa solo si se crea un nuevo objeto Session".

Por lo tanto, la primera vez que invoca getDefaultInstance utiliza el puerto especificado. Después de eso, el Session ya se ha creado y las llamadas subsiguientes al getDefaultInstance devolverán esa misma sesión e ignorarán las propiedades modificadas.

Pruebe utilizar Session.getInstance() en lugar de getDefaultInstance(), que crea una nueva Session cada vez, utilizando las propiedades proporcionadas.

Vale la pena leer los javadocs con mucho cuidado.

2

creo "Transport.send (msg)" no será teniendo en cuenta los detalles de la conexión que usted está proporcionando en sus propiedades. Utilizará su conexión que está definida por defecto.

El doc dice java

"Tenga en cuenta que enviar es un método estático que crea y gestiona su propia conexión. ** Cualquier conexión asociada con cualquier instancia de transporte empleado para llamar a este método se ignora y no se utiliza. Este método solo debe invocarse con el formato Transport.send (msg) ;, y nunca debe invocarse con una variable de instancia."**

En su lugar, lo he intentado con Transport.connect (smtphost, smtpport, usuario, contraseña) y funciona bastante bien.

Cuestiones relacionadas