how to configure a mail server using spring mvc and jsp? - java

I would just like to ask how can i setup a simple mail server and be able to send an email. Im using apache tomcat 6.0 as my localhost server and spring framework+jsp as well. I'm quite new on this. So if someone can give a nice tutorial, it will be of great help. thanks

Below is how you would get the spring configuration. probably applicationContext-mail.xml. Import that into applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"autowire="byName">
default-autowire="byName">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
</bean>
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="/WEB-INF/templates" />
</bean>
<!-- KINDLY MAINTAIN ALPHABETICAL ORDER THIS LINE ONWARDS -->
<bean id="notificationService" class="com.isavera.service.NotificationServiceImpl"
scope="prototype">
<property name="mailSender" ref="mailSender" />
<property name="freemarkerConfiguration" ref="freemarkerConfiguration" />
<property name="freemarkerTemplate" value="accountInformation.ftl" />
<property name="fromAddress" value="info#apnagenie.com" />
<property name="subject" value="Your account information" />
</bean>
Below is the NotificationServiceImpl
public class NotificationServiceImpl implements NotificationService, Runnable {
private boolean asynchronous = true;
private JavaMailSender mailSender;
private Configuration freemarkerConfiguration;
private String freemarkerTemplate;
private Map<String, Object> attributes;
private String deliveryAddress;
private String[] deliveryAddresses;
private String fromAddress;
private String subject;
private SimpleMailMessage message;
private MimeMessage mimeMessage;
public void deliver() {
message = new SimpleMailMessage();
if (getDeliveryAddresses() == null) {
message.setTo(getDeliveryAddress());
} else {
message.setTo(getDeliveryAddresses());
}
message.setSubject(subject);
message.setFrom(fromAddress);
// Merge the model into the template
final String result;
try {
result = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfiguration.getTemplate(appendApplicationName(freemarkerTemplate)), attributes);
message.setText(result);
if (asynchronous) {
Thread emailThread = new Thread(this);
emailThread.start();
} else {
run();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}

Related

Error occurred while sending email using spring frame work

I'm trying to send an email using spring framework. Im getting the following errors while trying to run the code. I use intellij IDE.
Exception in thread "main" java.lang.IllegalArgumentException: The 'original' message argument cannot be null
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.mail.SimpleMailMessage.<init>(SimpleMailMessage.java:73)
at com.howtodoinjava.demo.model.SimpleOrderManager.placeOrder(SimpleOrderManager.java:34)
at com.howtodoinjava.demo.model.SimpleOrderManager.main(SimpleOrderManager.java:48)
This is my code
package com.howtodoinjava.demo.model;
//import org.springframework.core.annotation.Order;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class SimpleOrderManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
//public String order;
//public String customer;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
public void placeOrder() {
// Do the business calculations...
// Call the collaborators to persist the order...
// Create a thread safe "copy" of the template message and customize it
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo("mygmail#gmail.com");
msg.setText("Message");
try{
this.mailSender.send(msg);
}
catch (MailException ex) {
// simply log it and go on...
System.err.println(ex.getMessage());
}
}
public static void main(String []args){
SimpleOrderManager obj = new SimpleOrderManager();
obj.placeOrder();
}
}
I have hard coded the message and email address for now.
edit:
Now I get this error After removing this.templateMessage.
Exception in thread "main" java.lang.NullPointerException
at com.howtodoinjava.demo.model.SimpleOrderManager.placeOrder(SimpleOrderManager.java:32)
at com.howtodoinjava.demo.model.SimpleOrderManager.main(SimpleOrderManager.java:42)
This is my spring-servlet.xml file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.howtodoinjava.demo" />
<mvc:annotation-driven />
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.mycompany.com"/>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="customerservice#mycompany.com"/>
<property name="subject" value="Your order"/>
</bean>
<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
<property name="mailSender" ref="mailSender"/>
<property name="templateMessage" ref="templateMessage"/>
</bean>
Assuming that you're following official Spring tutorial, you forgot to add beans definitions.
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.mycompany.com"/>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="customerservice#mycompany.com"/>
<property name="subject" value="Your order"/>
</bean>
<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
<property name="mailSender" ref="mailSender"/>
<property name="templateMessage" ref="templateMessage"/>
</bean>
In your code, this.templateMessage is null which results in exception.
Hope it helps!
You use wrong constructor, use:
SimpleMailMessage msg = new SimpleMailMessage();
instead
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
and you also will need to create mailSender:
private JavaMailSenderImpl createMailSender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setUsername(configuration.getUsername());
javaMailSender.setPassword(configuration.getPassword());
javaMailSender.setHost(configuration.getSmtpHost());
javaMailSender.setPort(configuration.getSmtpPort());
javaMailSender.setDefaultEncoding("UTF-8");
Properties properties = javaMailSender.getJavaMailProperties();
if (StringUtils.isNotEmpty(configuration.getFrom())) {
properties.put("mail.smtp.from", configuration.getFrom());
}
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.smtp.socketFactory.port", configuration.getSmtpPort());
properties.put("mail.smtp.socketFactory.fallback", false);
properties.put("mail.smtp.auth", true);
properties.put("mail.smtp.starttls.enable", true);
properties.put("mail.transport.protocol", "smtp");
properties.put("mail.debug", configuration.isDebug());
return javaMailSender;
}
just replace configuration calls, with your values.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'XXX'

I've been trying to deploy my project on my tomcat server but apparently, every time I try to start the server, I get this error in my catalina logs:
Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'mnpTranslationServiceImpl' defined in URL [file:/opt/tomcat/webapps/axis2/WEB-INF/springjdbc.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'mnpTranslationDAO' of bean class [com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl]:
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
here is my bean.xml which i named springjdbc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X1:3306/msdp" />
<property name="user" value="root" />
<property name="password" value="ehorizon" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="dataSourceHD" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X2:3306/hd" />
<property name="user" value="teligent" />
<property name="password" value="teligent" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="mpp2SubscribersDAO" class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersDAO">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="mpp2SubscribersService"
class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersServiceImpl">
<property name="mpp2SubscribersDAO">
<ref bean="mpp2SubscribersDAO" />
</property>
</bean>
<bean id="mnpTranslationDAO" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationDAO">
<property name="dataSource">
<ref bean="dataSourceHD" />
</property>
</bean>
<bean id="mnpTranslationServiceImpl" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl">
<property name="mnpTranslationDAO">
<ref bean="mnpTranslationDAO" />
</property>
</bean>
`
Here's the DAO file which the error says as not writable:
package com.e_horizon.jdbc.mnpTranslation;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import com.e_horizon.www.jdbc.common.BaseDAO;
public class mnpTranslationDAO extends BaseDAO {
private SimpleJdbcInsert jdbcCall;
public static String TABLE = "MNP_TRANSLATION";
public static String FIELD_MSISDN = "msisdn";
public static String FIELD_ROUTING_NUMBER = "routing_number";
public static String FIELD_LAST_UPDATE = "last_update";
public static String FIELD_ACTION = "action";
protected RowMapper getObjectMapper () {
return new mnpTranslationMapper();
}
public void save (mnpTranslation mnp) {
this.jdbcCall = this.getSimpleJdbcInsert().withTableName(TABLE);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put(FIELD_MSISDN, mnp.getMsisdn());
parameters.put(FIELD_ROUTING_NUMBER, mnp.getRouting_number());
parameters.put(FIELD_LAST_UPDATE, mnp.getLast_update());
parameters.put(FIELD_ACTION, mnp.getAction());
jdbcCall.execute(parameters);
}
}
Adding my model which contains the setters and getters (mnpTranslation.java):
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.Timestamp;
public class mnpTranslation {
private String msisdn;
private String routing_number;
private Timestamp last_update;
private String action;
public void setMsisdn (String msisdn) {
this.msisdn = msisdn;
}
public String getMsisdn () {
return this.msisdn;
}
public void setRouting_number (String routing_number) {
this.routing_number = routing_number;
}
public String getRouting_number () {
return this.routing_number;
}
public void setLast_update (Timestamp last_update) {
this.last_update = last_update;
}
public Timestamp getLast_update () {
return this.last_update;
}
public void setAction (String action) {
this.action = action;
}
public String getAction () {
return this.action;
}
}
[edit] I'm adding the rest of my java files so you could see more what I'm dealing with right now. Thanks a lot for checking this.
mnpTranslationService.java:
package com.e_horizon.jdbc.mnpTranslation;
public abstract interface mnpTranslationService {
public abstract void save (mnpTranslation mnp);
}
mnpTranslationServiceImpl.java:
package com.e_horizon.jdbc.mnpTranslation;
public class mnpTranslationServiceImpl {
private mnpTranslationDAO mnpTranslationDAO;
public void save (mnpTranslation mnp) {
this.mnpTranslationDAO.save(mnp);
}
}
mnpTranslationMapper.java:
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class mnpTranslationMapper implements RowMapper {
public Object mapRow (ResultSet result, int dex) throws SQLException {
mnpTranslation mnp = new mnpTranslation();
mnp.setMsisdn(result.getString("msisdn"));
mnp.setRouting_number(result.getString("routing_number"));
mnp.setLast_update(result.getTimestamp("last_update"));
mnp.setAction(result.getString("action"));
return mnp;
}
}
Please let me know if there's anything else you need to see. I'd gladly post it right away. Any help will be much appreciated.
The error message states that the problem is with your mnpTranslationServiceImpl class.
See error message
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

Spring JDBC Template- Decrypt password

I am using Spring JDBC template for establishing the connection with the database. The password is in the encrypted format and want to decrypt it with the help of JDBC template. In order to implement the same, I came to know that I have to override "DriverManagerDataSource" I tried to implement the same but have not succeeded.
<bean id="dataSource"
class="MyclassName">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
public class MyclassName extends DriverManagerDataSource {
#Override
public String getPassword() {
String password = super.getPassword();
//External API decryption call
EncrypterClassName encrypterClassName = new EncrypterClassName();
return encrypterClassName.decrypt(password);
}
}
I know I have to change the <property name="password" value="${jdbc.password}" to call the class I have implemented but not sure How to do the same.
Thank you.
I've written my own ProperyPlaceholderConfigurer which is invoked whenever a variable has to be replaced.
jdbc.password={base64}yourEncryptedSecret
 
import java.io.IOException;
import sun.misc.BASE64Decoder;
public class PropertyPlaceholderConfigurer
extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {
#Override
protected String convertPropertyValue(final String originalValue) {
String cryptString = "{base64}";
if (originalValue.startsWith(cryptString)) {
BASE64Decoder decoder = new BASE64Decoder();
String decodedPassword = null;
try {
decodedPassword = new String(decoder.decodeBuffer(originalValue.substring(cryptString.length())));
} catch (IOException e) {
e.printStackTrace();
}
return decodedPassword;
}
return originalValue;
}
}

How would I create the function for sending an email with the parameters set as String from, String to, String Subject, and String body?

I am trying to create a java batch email program that will send an email to a specific inbox with an excel report attachment. I have the function:
public void sendEmail(String to, String from, String subject, String body)
{
}
I am trying to use Spring, and I'm trying to stick to xml configuration in the appcontext file for now instead of annotations (for learning purposes). I want to inject a static resource which is an excel file, and for learning purposes for this module I am avoiding using FileSystemResource for the attachment per my mentor/teacher. I also don't need the body to say anything. The subject line will be "Report" for dummy purposes. Here is what I have so far, just need the meat of the actual email function that's needed so I could pass the parameters of sendEmail by reference in the main class:
public class SendEmail
{
private JavaMailSender mailSender;
public SendEmail(JavaMailSender ms)
{
this.mailSender = ms;
}
public void sendEmail(String from, String to, String Subject, String body)
{
MimeMessage message = mailSender.createMimeMessage();
try
{
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("whatever#xyz.com");
helper.setText("Test email!");
mailSender.send(message);
}
catch (MessagingException e)
{
throw new MailParseException(e);
}
}
public void setMailSender(JavaMailSender mailSender)
{
this.mailSender = mailSender;
}
}
This is the applicationContext.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=`
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.transportation"/>
<bean id = "mailSender" class = "org.springframework.mail.javamail.JavaMailSenderImpl">
<property name = "host" value = "Whatever" />
<property name = "port" value = "25" />
</bean>
<bean id = "sendEmail" class = "com.transportation.email.util.SendEmail">
<constructor-arg ref="mailSender"/>
</bean>
</beans>
Try this one.
public void sendMail(final String messageStr, final boolean isHtml) throws MessagingException {
final MimeMessage message = mailSender.createMimeMessage();
final MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(simpleMailMessage.getFrom());
helper.setTo(simpleMailMessage.getTo());
helper.setCc(simpleMailMessage.getCc());
helper.setSubject(simpleMailMessage.getSubject());
helper.setText(messageStr, isHtml);
helper.addInline("myFile", ResourceUtil.loadResourceAsFileSystemResource("NameOfresource"));
mailSender.send(message);
}
public static FileSystemResource loadResourceAsFileSystemResource(final String fileRoute) {
File file = null;
FileSystemResource fileSystemResource;
try {
file = new ClassPathResource(fileRoute).getFile();
fileSystemResource = new FileSystemResource(file);
}
catch (final IOException e) {
fileSystemResource = null;
}
return fileSystemResource;
}
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.host">${mail.smtp.host}</prop>
<prop key="mail.smtp.port">${mail.smtp.port}</prop>
</props>
</property>
</bean>
<bean id="sfErrorMailSender" class="XXX.MailSender">
<property name="mailSender" ref="mailSender" />
<property name="simpleMailMessage" ref="sfErrorNotificationMailMessage" />
</bean>
<bean id="sfErrorNotificationMailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.message.error.sf.to}" />
<property name="to" value="${mail.message.error.sf.from}" />
<property name="subject" value="${mail.message.error.sf.subject}" />
<property name="text" value="${mail.message.error.sf.body}" />
<property name="cc" value="${mail.message.error.sf.cc}" />
</bean>

Spring mail support - no subject

I have updated my libraries, and now e-mails are sent without subject. I don't know where this happened...
Mail API is 1.4.3., Spring 2.5.6. and Spring Integration Mail 1.0.3.RELEASE.
<!-- Definitions for SMTP server -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
</bean>
<bean id="adminMailTemplate" class="org.springframework.mail.SimpleMailMessage" >
<property name="from" value="${mail.admin.from}" />
<property name="to" value="${mail.admin.to}" />
<property name="cc">
<list>
<value>${mail.admin.cc1}</value>
</list>
</property>
</bean>
<!-- Mail service definition -->
<bean id="mailService" class="net.bbb.core.service.impl.MailServiceImpl">
<property name="sender" ref="mailSender"/>
<property name="mail" ref="adminMailTemplate"/>
</bean>
And properties mail.host,mail.username,mail.password,mail.admin.from,mail.admin.to,
mail.admin.cc1.
Java class:
/** The sender. */
private MailSender sender;
/** The mail. */
private SimpleMailMessage mail;
public void sendMail() {
this.mail.setSubject("Subject");
this.mail.setText("msg body");
try {
getSender().send(this.mail);
} catch (MailException e) {
log.error("Error sending mail!",e);
}
}
public SimpleMailMessage getMail() {
return this.mail;
}
public void setMail(SimpleMailMessage mail) {
this.mail = mail;
}
public MailSender getSender() {
return this.sender;
}
public void setSender(MailSender mailSender1) {
this.sender = mailSender1;
}
Everything worked before, I am wondering if there may be any conflicts with new libraries.
Finally - I had the time to resolve this.
In pom.xml, I have added java mail dependency and remove exclusion for geronimo javamail in apache axis transport http dependency.
I expect it's something to do with the way that you're injecting a singleton SimpleMailMessage into your bean. This is not thread-safe, since every call to your sendMail method will be using the same underlying SimpleMailmessage object. It's quite possible that some implementation change in the new libraries now means this is broken.
SimpleMailMessage has a copy constructor, so you should do it like this:
<bean id="mailService" class="net.bbb.core.service.impl.MailServiceImpl">
<property name="sender" ref="mailSender"/>
<property name="template" ref="adminMailTemplate"/>
</bean>
and
private SimpleMailMessage template;
public void setTemplate(SimpleMailMessage template) {
this.template = template;
}
public void sendMail() {
SimpleMailMessage message = new SimpleMailMessage(template);
message.setSubject("Subject");
message.setText("msg body");
try {
getSender().send(message);
} catch (MailException e) {
log.error("Error sending mail!",e);
}
}

Categories