web-dev-qa-db-fra.com

Comment changer de port JavaMail

J'écris un petit Java application à l'aide de JavaMail qui envoie à l'utilisateur un email automatisé. Ils peuvent choisir entre (pour l'instant) deux ports: 25 et 587. Le port peut être sélectionné via une radio bouton sur l'interface graphique.

J'ai ajouté un bouton de test pour permettre à l'utilisateur de tester les paramètres de messagerie (y compris le port). Toutefois, pour une raison quelconque, une fois que l'utilisateur tente d'envoyer un courrier électronique de test, le port ne peut pas être modifié. JavaMail utilisera toujours le port du courrier électronique d'origine.

Exemple: L'utilisateur tente d'envoyer un courrier électronique sur le port 25 et JavaMail dit qu'il ne peut pas se connecter sur le port 25 (par exemple, l'hôte SMTP utilise un autre port). Utilisateur clique sur le port 587 et essaie d'envoyer un nouvel email. JavaMail jette une erreur disant qu'il ne peut pas se connecter sur le port 25, à nouveau.

Je suis une sorte de creuser pourquoi. Chaque fois qu'un nouvel e-mail de test est envoyé un nouvel objet SendMailOnduSuThentistication est créé. Dans cette classe, les propriétés sont toujours réinitialisées au port approprié. Chaque fois que je débogé, aussi loin que je peux le voir, toutes les variables sont correctes et associées au bon port. Y a-t-il quelque chose qui se passe à l'intérieur du transport qui me manque?

Dans l'interface graphique avant:

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();
}

Dans la classe Email Sender:

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);
}
18
PaulV

Cela se produit parce que vous utilisez getDefaultInstance() qui dit :

Obtenez l'objet de session par défaut. Si une valeur par défaut n'a pas encore été configurée, un nouvel objet de session est créé et installé comme défaut.

Et que l'argument Properties est "utilisé uniquement si un nouvel objet de session est créé".

Donc, la première fois que vous invoquez getDefaultInstance il utilise votre port spécifié. Après cela, le Session a déjà été créé et les appels ultérieurs vers getDefaultInstance renvoient la même session et ignoreront les propriétés modifiées.

Essayez d'utiliser Session.getInstance() au lieu de getDefaultInstance(), qui crée une nouvelle Session à chaque fois, à l'aide des propriétés fournies.

Il paie très attentivement les Javadocs.

23
skaffman

Je pense que "transport.send (msg)" ne prend pas en compte les détails de la connexion que vous fournissez dans vos propriétés. Il utilisera sa connexion qui est définie par défaut.

Le Java Doc dit

"Notez que l'envoi est une méthode statique qui crée et gère sa propre connexion. ** Toute connexion associée à toute instance de transport utilisée pour appeler cette méthode est ignorée et non utilisée. Cette méthode ne doit être invoquée qu'avec le transport de formulaire.Send (msg); et ne doit jamais être invoqué à l'aide d'une variable d'instance. "**

Au lieu de cela, j'ai essayé avec transport.Connect (Smtphost, Smtpport, utilisateur, mot de passe) et ça fonctionne assez bien.

3
Sure