JAVA Spring mail sending via gmail - email

I want to send emails using gmail smtp server and spring mail sender, it doesn' throw any exceptions but my mail isn't sent i don't receive it.
Here's how Service looks:
#Service
public class MailSenderService {
#Autowired
public MailSender mailSender;
public void prepareAndSend(String recipient, String message) {
try {
SimpleMailMessage mail = new SimpleMailMessage();
String from = "testSender1#gmail.com";
String to = "testRecipient1#gmail.com";
String subject = "Test subject";
mail.setFrom(from);
mail.setTo(recipient);
mail.setSubject(subject);
mail.setText(message);
mailSender.send(mail);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
AppProperties
spring.mail.host = smtp.gmail.com
spring.mail.username = ********#gmail.com
spring.mail.password = ********
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.socketFactory.port = 465
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback = false
spring.mail.properties.mail.smtp.ssl.enable = true
And pom dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
I deploy my app on port 8080 and just call this service with these two parameters, no exception is caught but in my testRecipient1 inbox i don't find any new mail, what have i missed ?

You could also try the below settings but i couldn't give more information regarding this as it will be a long post. However GeeksForGeeks do explain what everything does in the spring mail properties, also google has it's own guidelines which you can find here
p.s. I have also disabled the Access to less secure applications from the gmail account settings
Below is application.properties
spring.mail.host=smtp.gmail.com
spring.mail.port=465
spring.mail.username=xxxxx#gmail.com
spring.mail.password=*****
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.default-encoding=UTF-8
Below is my email service class (not that professional but for a personal projects it does the trick I need)
#Service
#AllArgsConstructor
#Slf4j
public class EmailService implements EmailSender {
private final JavaMailSender mailSender;
#Override
#Async
public void send(String to, String email) {
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8");
helper.setText(email, true);
helper.setTo(to);
helper.setSubject("Your subject");
helper.setFrom("xxxxxx#gmail.ro");
mailSender.send(mimeMessage);
} catch (MessagingException e) {
log.error("failed to send email", e);
throw new IllegalStateException("failed to send email");
}
}
}

If You did not use SSL Certificate in You web application than try my code, it work perfectly in spring boot, text mail and HTML Mail both working perfectly.
#Autowired
private JavaMailSender mailSender;
#RequestMapping(value="/ShareVecancy",method=RequestMethod.GET)
public ModelAndView sendEmailToReference(HttpServletRequest request,HttpSession session){
try {
MimeMessage mail = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mail, true);
messageHelper.setTo("reciverEmail#mail.com");
messageHelper.setSubject("Testing mail");
messageHelper.setText("HTML Text or Any text You want to send ", true);
mailSender.send(mail);
} catch (MailException e) {
e.printStackTrace();
}
}
Property File:::
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=xyz#gmail.com
spring.mail.password=*******
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.default-encoding=UTF-8
Dependency ::
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

application.yml example (tested with Spring Boot 2.1.1):
spring
mail:
host: smtp.gmail.com
username: youremail#gmail.com
port: 587
password: ******
protocol: smtp
properties:
mail:
smtp:
starttls:
enable: true

Related

Adding nick field to registration new xmpp username using ejabberd

I wanted to send "nick" field from client to register new username with ejabberd in band registration. but Server is sending only username, password and instructions fields back to client to fill. I have checked below mod_register to modify these fields but none provide is available.
https://docs.ejabberd.im/admin/configuration/#mod-register
2018-05-29 23:01:08.426 [debug] <0.4613.3>#xmpp_socket:send:218 (tls|<0.4613.3>) Send XML on stream = <<"
<iq xml:lang='en' from='xmpp.test.in' type='result' id='mCbQBXKp-Sd4'>
<query xmlns='jabber:iq:register'>
<username/>
<password/>
<instructions>Choose a username and password to register with this server</instructions>
</query>
</iq>">>
Can any help me how to get nick included in registration itself?
If you are using Smack client for Android you can send additional attributes in createAccount method like:
public void signup(String user, String password, String nickname) throws SmackInvocationException {
connect();
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("name", nickname);
try {
AccountManager.getInstance(con).createAccount(user, password, attributes);
} catch (Exception e) {
throw new SmackInvocationException(e);
}
}
Another approach is to use Vcard with VcardManager and set nickname in smack like (after login or signup):
private Context context;
private XMPPConnection con;
public SmackVCardHelper(Context context, XMPPConnection con) {
this.context = context;
this.con = con;
}
public void save(String nickname) throws SmackInvocationException {
VCard vCard = VCardManager.getInstanceFor(connection).loadVCard();
try {
vCard.setNickName(nickname);
vCard.saveVCard(vcard);
} catch (Exception e) {
throw new SmackInvocationException(e);
}
}

sending an email from an forms Application (why dosen't it work)

I am trying to learn how to send a simple email with c# visual studio forms Application. (it could also be a console application for all I care). Here is the code I have(I don't see what's wrong with the code, it should work right?):
using System.Net.Mail;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("(here is my email)");
mail.To.Add("(here is my email)");
mail.Subject = "toja";
mail.Body = "ja";
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("(here is my email)", "(here is my password)");
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
I use the following to send email from C# Forms application and it works.
Maybe you should try adding the smtp.UseDefaultCredentials = false property and set the Credentials property?
// Create our new mail message
MailMessage mailMessage = new MailMessage();
mailMessage.To.Add("toAddress");
mailMessage.From = new MailAddress("fromAddress");
mailMessage.Subject = "subject";
mailMessage.Body = "body";
// Set the IsBodyHTML option if it is HTML email
mailMessage.IsBodyHtml = true;
// Enter SMTP client information
SmtpClient smtpClient = new SmtpClient("mail.server.address");
NetworkCredential basicCredential = new NetworkCredential("username", "password");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = basicCredential;
smtpClient.Send(mailMessage);
If using Gmail you can find the SMTP server information here https://support.google.com/a/answer/176600?hl=en. It looks like the address is smtp.gmail.com and the port is 465 for SSL or 587 for TLS. I would suggest you try using default port 25 first to make sure your email goes through, then adjust to a different port if you need to.

Created sendgrid email template, how to call it from Java

I have created email template in sendgrid - with substitutable values;
I get the JSON payload (contains substitute values) for processing email from rabbitMQ queue. My question is how to call the sendgrid email template from Java?
I found the solution, the way to call sendgrid template and email through sendgrid as below:
SendGrid sendGrid = new SendGrid("username","password"));
SendGrid.Email email = new SendGrid.Email();
//Fill the required fields of email
email.setTo(new String[] { "xyz_to#gmail.com"});
email.setFrom("xyz_from#gmail.com");
email.setSubject(" ");
email.setText(" ");
email.setHtml(" ");
// Substitute template ID
email.addFilter(
"templates",
"template_id",
"1231_1212_2323_3232");
//place holders in template, dynamically fill values in template
email.addSubstitution(
":firstName",
new String[] { firstName });
email.addSubstitution(
":lastName",
new String[] { lastName });
// send your email
Response response = sendGrid.send(email);
This is my working soloution .
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sendgrid.*;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class MailUtil {
public static void main(String[] args) throws IOException {
Email from = new Email();
from.setEmail("fromEmail");
from.setName("Samay");
String subject = "Sending with SendGrid is Fun";
Email to = new Email();
to.setName("Sam");
to.setEmail("ToEmail");
DynamicTemplatePersonalization personalization = new DynamicTemplatePersonalization();
personalization.addTo(to);
Mail mail = new Mail();
mail.setFrom(from);
personalization.addDynamicTemplateData("name", "Sam");
mail.addPersonalization(personalization);
mail.setTemplateId("TEMPLATE-ID");
SendGrid sg = new SendGrid("API-KEY");
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
throw ex;
}
}
private static class DynamicTemplatePersonalization extends Personalization {
#JsonProperty(value = "dynamic_template_data")
private Map<String, String> dynamic_template_data;
#JsonProperty("dynamic_template_data")
public Map<String, String> getDynamicTemplateData() {
if (dynamic_template_data == null) {
return Collections.<String, String>emptyMap();
}
return dynamic_template_data;
}
public void addDynamicTemplateData(String key, String value) {
if (dynamic_template_data == null) {
dynamic_template_data = new HashMap<String, String>();
dynamic_template_data.put(key, value);
} else {
dynamic_template_data.put(key, value);
}
}
}
}
Here is an example from last API spec:
import com.sendgrid.*;
import java.io.IOException;
public class Example {
public static void main(String[] args) throws IOException {
Email from = new Email("test#example.com");
String subject = "I'm replacing the subject tag";
Email to = new Email("test#example.com");
Content content = new Content("text/html", "I'm replacing the <strong>body tag</strong>");
Mail mail = new Mail(from, subject, to, content);
mail.personalization.get(0).addSubstitution("-name-", "Example User");
mail.personalization.get(0).addSubstitution("-city-", "Denver");
mail.setTemplateId("13b8f94f-bcae-4ec6-b752-70d6cb59f932");
SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
throw ex;
}
}
}
https://github.com/sendgrid/sendgrid-java/blob/master/USE_CASES.md
Recently Sendgrid upgraded the Maven version v4.3.0 so you don't have to create additional classes for dynamic data content. Read more from this link https://github.com/sendgrid/sendgrid-java/pull/449
If you're doing a spring-boot maven project, You'll need to add the sendgrid-java maven dependency in your pom.xml. Likewise, in your application.properties file under resource folder of the project, add SENDGRID API KEY AND TEMPLATE ID under attributes such as spring.sendgrid.api-key=SG.xyz and templateId=d-cabc respectively.
Having done the pre-setups. You can create a simple controller class as the one given below:
Happy Coding!
#RestController
#RequestMapping("/sendgrid")
public class MailResource {
private final SendGrid sendGrid;
#Value("${templateId}")
private String EMAIL_TEMPLATE_ID;
public MailResource(SendGrid sendGrid) {
this.sendGrid = sendGrid;
}
#GetMapping("/test")
public String sendEmailWithSendGrid(#RequestParam("msg") String message) {
Email from = new Email("bijay.shrestha#f1soft.com");
String subject = "Welcome Fonesal Unit to SendGrid";
Email to = new Email("birat.bohora#f1soft.com");
Content content = new Content("text/html", message);
Mail mail = new Mail(from, subject, to, content);
mail.setReplyTo(new Email("bijay.shrestha#f1soft.com"));
mail.setTemplateId(EMAIL_TEMPLATE_ID);
Request request = new Request();
Response response = null;
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
response = sendGrid.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
return "Email was successfully sent";
}
}
This is based on verision com.sendgrid:sendgrid-java:4.8.3
Email from = new Email(fromEmail);
Email to = new Email(toEmail);
String subject = "subject";
Content content = new Content(TEXT_HTML, "dummy value");
Mail mail = new Mail(from, subject, to, content);
// Using template to send Email, so subject and content will be ignored
mail.setTemplateId(request.getTemplateId());
SendGrid sendGrid = new SendGrid(SEND_GRID_API_KEY);
Request sendRequest = new Request();
sendRequest.setMethod(Method.POST);
sendRequest.setEndpoint("mail/send");
sendRequest.setBody(mail.build());
Response response = sendGrid.api(sendRequest);
You can also find fully example here:
Full Email object Java example

send email in java

I am creating an application where I want to send an email to my clients.When i compiled the below code its ok but when i run it gives me error as follows
java code:
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
public class SendEmail
{
public static void main(String [] args)
{
String to = "prakash_d22#rediffmail.com";
String from = "web#gmail.com";
String host = "localhost";
Properties properties = System.getProperties();
properties.setProperty("smtp.gmail.com", host);
Session session = Session.getDefaultInstance(properties);
try{
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
Transport.send(message);
System.out.println("Sent message successfully....");
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
error:
Please guide me.
String host = "smtp.gmail.com";
Properties properties = new Properties();
set following properties
properties .put("mail.smtp.starttls.enable", "true");
properties .put("mail.smtp.host", host);
properties .put("mail.smtp.user", username);
properties .put("mail.smtp.password", password);
properties .put("mail.smtp.port", "587");
properties .put("mail.smtp.auth", "true");
Have you read the Fundamentals of the JavaMail API?
Anyways, from what I can tell the issue is that you're using invalid configuration.
properties.setProperty("smtp.gmail.com", host);
As you can see in the JavaMail API documentation, JavaMail does not support a property named smtp.gmail.com. What you probably intended was actually...
properties.setProperty("mail.smtps.host", host);
I suspect you wish to use Gmail's SMTPS server, not one hosted on localhost as you have it now, so I'd advise changing your code such that...
final String host = "smtp.gmail.com";
You also wish to use authnetication, which JavaMail suggests you can do in their FAQ on Gmail as follows:
properties.setProperty("mail.smtps.auth", "true");
Note that Gmail requires authenticating to send mail as such. It appears another answer suggested you can configure the username/password using the session properties; unfortunately, this is incorrect.
What you want to do is use an Authenticator.
final Session session = Session.getInstance(properties, new Authenticator() {
static final PasswordAuthentication AUTH = new PasswordAuthentication(USER, PASS);
protected PasswordAuthentication getPasswordAuthentication() {
return AUTH;
}
});

Generating random session id whenever user uses login() in web services

Am new to web services. Am trying to generate unique session id for every login that a user does, in web services.
What I thought of doing is,
Write a java file which has the login and logout method.
Generate WSDL file for it.
Then generate web service client(using Eclipse IDE), with the WSDl file which I generate.
Use the generated package(client stub) and call the methods.
Please let me know if there are any flaws in my way of implementation.
1. Java file with the needed methods
public String login(String userID, String password) {
if (userID.equalsIgnoreCase("sadmin")
&& password.equalsIgnoreCase("sadmin")) {
System.out.println("Valid user");
sid = generateUUID(userID);
} else {
System.out.println("Auth failed");
}
return sid;
}
private String generateUUID(String userID) {
UUID uuID = UUID.randomUUID();
sid = uuID.toString();
userSessionHashMap = new HashMap<String, String>();
userSessionHashMap.put(userID, sid);
return sid;
}
public void logout(String userID) {
Set<String> userIDSet = userSessionHashMap.keySet();
Iterator<String> iterator = userIDSet.iterator();
if (iterator.equals(userID)) {
userSessionHashMap.remove(userID);
}
}
2. Generated WSDL file
Developed the web service client from the wsdl.
4. Using the developed client stub.
public static void main(String[] args) throws Exception {
ClientWebServiceLogin objClientWebServiceLogin = new ClientWebServiceLogin();
objClientWebServiceLogin.invokeLogin();
}
public void invokeLogin() throws Exception {
String endpoint = "http://schemas.xmlsoap.org/wsdl/";
String username = "sadmin";
String password = "sadmin";
String targetNamespace = "http://WebServiceLogin";
try {
WebServiceLoginLocator objWebServiceLoginLocator = new WebServiceLoginLocator();
java.net.URL url = new java.net.URL(endpoint);
Iterator ports = objWebServiceLoginLocator.getPorts();
while (ports.hasNext())
System.out.println("ports Iterator size-->" + ports.next());
WebServiceLoginPortType objWebServiceLoginPortType = objWebServiceLoginLocator
.getWebServiceLoginHttpSoap11Endpoint();
String sid = objWebServiceLoginPortType.login(username, password);
System.out.println("sid--->" + sid);
} catch (Exception exception) {
System.out.println("AxisFault at creating objWebServiceLoginStub"
+ exception);
exception.printStackTrace();
}
}
On running the this file, I get the following error.
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.net.ConnectException: Connection refused: connect
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.net.ConnectException: Connection refused: connect
Can anyone suggest an alternate way of handling this task ? And what could probably be the reason for this error.
Web services are supposed to be stateless, so having "login" and "logout" web service methods doesn't make much sense.
If you want to secure web services calls unfortunately you have to code security into every call. In your case, this means passing the userId and password to every method.
Or consider adding a custom handler for security. Read more about handlers here.