8
I created a system where the user registers and the password is sent by email. If you cannot send the email, it generates an error and does not create the user, notifying the same. It was working while using own mail server.
I recently started using a Gmail account to send emails. From there the function does not generate any more error when Gmail cannot deliver the message. With this the user does not know that a problem has occurred and does not receive the password.
import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
// ... Demais imports
@ViewScoped
public class Mailer implements Serializable{
private static final long serialVersionUID = 1L;
@Inject
private PropriedadesEmail propriedadesEmail;
private String mailTo;
private String mailCC;
private String mailSubject;
private String mailBody;
public void sendMail() throws NegocioException {
try{
MimeMessage generateMailMessage = propriedadesEmail.mineMessage(); // new MimeMessage(getMailSession);
generateMailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(this.mailTo));
if(this.mailCC != null)
generateMailMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(this.mailCC));
generateMailMessage.setSubject(this.mailSubject);
generateMailMessage.setFrom(propriedadesEmail.getMailUsername());
generateMailMessage.setContent(this.mailBody, "text/html");
Transport transport = propriedadesEmail.getMailSession().getTransport("smtp");
transport.connect( propriedadesEmail.getMailServerHost()
,propriedadesEmail.getMailUsername()
,propriedadesEmail.getMailPassword()
);
transport.sendMessage(generateMailMessage, generateMailMessage.getAllRecipients());
transport.close();
} catch (AddressException e) {
System.out.println("-------- ERRO AddressException e "+e.getMessage());
e.printStackTrace();
throw new NegocioException(TrataErro.buscaErroEmail(e, "Problemas ao enviar email"));
} catch (MessagingException e) {
e.printStackTrace();
System.out.println("-------- ERRO MessagingException e "+e.getMessage());
throw new NegocioException(TrataErro.buscaErroEmail(e, "Problemas ao enviar email"));
} catch (Exception e) {
e.printStackTrace();
throw new NegocioException(TrataErro.buscaErroEmail(e, "Problemas ao enviar email"));
}
}
// ... Demais metodos e clases
}
Property Classemail
@ApplicationScoped
public class PropriedadesEmail implements Serializable{
private static final long serialVersionUID = 1L;
private String mailServerHost;
private String mailServerPort;
private String mailEnableSsl;
private String mailEnableStarttls;
private String mailAuth;
private String mailUsername;
private String mailPassword;
private Session mailSession;
@PostConstruct
private void init(){
Properties props = new Properties();
try {
props.load(ManipulacaoProperties.buscaFile(ManipulacaoProperties.CONFIG_EMAIL));
mailServerHost = props.getProperty("mail.server.host");
mailServerPort = props.getProperty("mail.server.port");
mailEnableSsl = props.getProperty("mail.enable.ssl");
mailEnableStarttls = props.getProperty("mail.enable.starttls");
mailAuth = props.getProperty("mail.auth");
mailUsername = props.getProperty("mail.username");
mailPassword = props.getProperty("mail.password");
mailSession = Session.getDefaultInstance(mailServerProperties(), null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new NegocioException("Problemas ao abrir o arquivo de configuração. Contate o administrador");
}
}
public MimeMessage mineMessage() {
return new MimeMessage(this.getMailSession());
}
private Properties mailServerProperties() {
Properties props = new Properties();
try {
props.load(ManipulacaoProperties.buscaFile(ManipulacaoProperties.CONFIG_EMAIL));
Properties mailServerProperties = System.getProperties();
mailServerProperties.put("mail.smtp.port", this.getMailServerPort());
mailServerProperties.put("mail.smtp.auth", this.getMailAuth());
mailServerProperties.put("mail.smtp.starttls.enable", this.getMailEnableStarttls());
return mailServerProperties;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new NegocioException("Problemas ao abrir o arquivo de configuração. Contate o administrador");
}
}
mail properties.
mail.server.host=smtp.gmail.com
mail.server.port=587
mail.enable.ssl=false
mail.enable.starttls=true
mail.auth=true
[email protected]
mail.password=*******************
Email returned with gmail error.
Mail Delivery Subsystem
Address not found Message not delivered to [email protected] because the address was not found. Check for typos or spaces unnecessary and try again.
The response from the remote server was: 550 5.1.1 : Recipient address Rejected: User Unknown in virtual mailbox table
Final-Recipient: rfc822; [email protected] Action: failed Status: 5.1.1 Remote-MTA: dns; mail2.transportesalvorada.com.br. (201.148.108.74, the server for the Domain transportesalvorada.com.br. ) Diagnostic-Code: smtp; 550 5.1.1 : Recipient address Rejected: User Unknown in virtual mailbox table Last-Attempt-Date: Wed, 08 Mar 2017 05:53:40 -0800 (PST)
When I used gmail to send emails, gmail itself wouldn’t let a "less secure application" access my account, I had to go to gmail and disable a security option to let my application access the account and send emails.
– Erick Maia
I’m managing to send the emails. My problem is if the user reports an invalid email and gmail cannot send the Addressexception error for example is not generated.
– Marcelo
Which e-mail invalid you are using for testing? The
AddressException
occurs during the parse ofString
to create an objectInternetAddress
if the format of Pattern of email is invalid, that is, at this time you are not yet connected to gmail. The exception made when the recipient is not present isSendFailedException
during the execution of the methodsendMessage
classTransport
.– Felipe Marinho
I put Sendfailedexception as suggested but I still don’t get the exception in the system. I only receive an email in the gmail itself informing the error.
– Marcelo
Edit the question and include the email gmail sent you. Nowadays even to configure Outlook to use Gmail you need to go to gmail and give permission. With your application it should be no different.
– Antonio Alexandre
Edited question as suggested.
– Marcelo
While receiving your email sending request, Gmail does not accuse that the email recipient is invalid because it is not invalid - it just does not exist on the destination provider; so there is no exception. And the email is actually sent to the recipient email! What happens next is that the recipient email provider identifies that the email does not exist there and then responds with another email. If you try to inform a non-existent recipient of Gmail, as it is the Gmail that is sending it has how to verify it in the act and there will probably be exception.
– Caffé
And there’s some way to treat that?
– Marcelo
@Marcelo You will have to change the logic of your system according to your requirements. For example: you could not send a password but rather let the person enter one; then you send an email with a link including a hash where the person clicking confirms that the email is his or her own, and only then does email become reliable for you to send new passwords in the future if that’s the case. You can monitor responses to the email sent to see if the provider has rejected, but note that this is not good for much because the person can enter, even unintentionally, with an existing email that does not belong to them.
– Caffé
But even letting the user enter the password by sending a link to confirm would fall into the same problem. Anyway thanks.
– Marcelo