Spring Email using Office 365

I’m using javamail package in raw format so far. I prefer to split all the communications (email, social media…) and run it as a spring REST API server. Here is the initial code snippet.

Take STS or Eclipse, Start a Spring Starter Project and follow the instructions given below.

Dependencies

Maven Dependencies are given below.

4.0.0

org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE

org.grassfield
messenger
0.0.1-SNAPSHOT
messenger
MultiPlatformMessenger

1.8
UTF-8
UTF-8

org.springframework.boot
spring-boot-starter-mail

org.springframework.boot
spring-boot-starter-web

org.springframework.boot
spring-boot-starter-test
test

org.springframework.boot
spring-boot-maven-plugin

User.java

This is an entity class for the user.


package org.grassfield.msg;

import org.springframework.stereotype.Component;

/**
* The Class User.
* @author Murugapandian Ramaiah
* @version 1.0
*/
@Component
public class User {
private String email;

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

}

 

 

MailService.java

As the name implies this is the email sending service.


package org.grassfield.msg;

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

@Service
public class MailService {
@Autowired
private JavaMailSender sender;

public void sendEmail (User user) {
SimpleMailMessage mail = new SimpleMailMessage();
mail.setFrom(user.getEmail());
mail.setTo(user.getEmail());
mail.setSubject("Testing Email Service");
mail.setText("Test email content");
this.sender.send(mail);
}

public void sendEmailWithAttachment(User user) throws MessagingException, UnsupportedEncodingException {
MimeMessage mimeMsg = this.sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, true);
helper.setFrom(new InternetAddress(user.getEmail(), user.getEmail()));
helper.setTo(user.getEmail());
helper.setSubject("Multipart email");
helper.setText("Content of this email");
this.sender.send(mimeMsg);
}

}

 

 

MailController.java

Here is the REST controller.


package org.grassfield.msg;

import java.io.UnsupportedEncodingException;

import javax.mail.MessagingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* The Class MailController.
* @author Murugapandian Ramaiah
* @version 1.0
*/
@RestController
public class MailController {

/** The service. */
@Autowired
private MailService service;

/** The user. */
@Autowired
private User user;

@RequestMapping("test-plain-text-email")
public String testPlainTextEmail() {
user.setEmail("recipient@office365 email address");
service.sendEmail(user);
return "Email sent";
}

@RequestMapping("test-multipart-email")
public String testMultipartEmail() throws MessagingException, UnsupportedEncodingException {
user.setEmail("recipient@office365 email address");
service.sendEmailWithAttachment(user);
return "Email sent";
}

}

 

 

application.properties


spring.mail.host = smtp.office365.com
spring.mail.username = user@office 365 account
spring.mail.password = office 365 password
spring.mail.port=587
spring.mail.properties.mail.smtp.port=587
spring.mail.properties.mail.transport.protocol=smtps
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.enable=false
spring.mail.properties.mail.smtp.timeout=15000
spring.mail.properties.mail.smtp.connectiontimeout=15000
spring.mail.properties.mail.smtp.socketFactory.fallback = true
spring.mail.properties.mail.mail.debug=true
spring.mail.properties.mail.pop3.host=pop email address
spring.mail.properties.mail.pop3.port=110
spring.mail.properties.mail.pop3.starttls.enable=true
spring.mail.properties.mail.pop3.store=pop3s
spring.mail.properties.pop.pop3.username=pop username
spring.mail.properties.pop.pop3.password=pop password
spring.mail.properties.pop.pop3.folder=INBOX

 

 

Test

Test your services with these.

curl -X GET -i http://localhost:8080/test-plain-text-email

curl -X GET -i http://localhost:8080/test-multipart-email

Advertisements

Iterating a list in Thymeleaf

I started Apache tiles in 2010. It is convenient for the tasks I am doing. Thymeleaf picked up in parallel. By the time I read Thymeleaf template engine is trying to replace JSP, I left it as such and continue using Tiles 🙂

Anyway I wanted to see what is it. I was trying to iterate a list using th: namespace.

I have a controller like this, which returns a list of my entity.


@GetMapping (value = "/")
public String index(Locale locale, Model model) {
RestTemplate restTemplate = new RestTemplate();
List fromRest = restTemplate.getForObject("http://localhost:8081/api/v1/feeditems", List.class);
model.addAttribute("feeditems", (List)fromRest);
return "index";
}

And it is


<div th:if="${#lists.isEmpty(feeditems)}">
	Empty
</div>
<div th:if="not ${#lists.isEmpty(feeditems)}">
	Not Empty
</div>

<div th:each="post:${feeditems}">
	<div th:text="${post.title}"></div>
</div>

Here is the output:

Iterate through thymeleaf

I captured this the on the way to Kandy in Sri Lanka

I captured this the on the way to Kandy in Sri Lanka

Could not write JSON: (was java.lang.NullPointerException)

It was a dirty exception I faced few weeks back. I was trying to to consume a REST API call using postForEntity.

Unfortunately my ID variable was in primitive long instead of Long. I hit with the following error. I had been roaming around without a clue.

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException)

Ref: https://stackoverflow.com/questions/24805043/org-springframework-http-converter-httpmessagenotwritableexception-could-not-wr

I shot this soft white sand beach at Coney Island recently

I shot this soft white sand beach at Coney Island recently

detached entity passed to persist

I am in mid of a crud operation. This exception hit me today, when I updated an entity with @ManyToOne(cascade = CascadeType.ALL) relationship.

org.hibernate.PersistentObjectException: detached entity passed to persist: org.grassfield.feed.entity.Feed

To solve this bidirectional consistency problem, I need to change CascadeType.ALL to CasecaseType.MERGE.

Recently I shot this pretty lady (or mighty gentleman?) at Coney Island. This has no relation with this post anyway.

Recently I shot this pretty lady (or mighty gentleman?) at Coney Island. This has no relation with this post anyway.

 

 

ClassCastException: RestTemplate returning List instead of List

Problem:

I have a POJO entity, say org.grassfield.Employee. I expose this as a REST services.

I consume this REST service,


List employeeList = restTemplate.getForObject(
"http://localhost:8080/api/v1/employees" ,
List.class);

Instead of getting Employee object, I’m getting LinkedHashMap. So my code fails with ClassCastException: RestTemplate returning List<LinkedHashMap> instead of List<Employee>

Solution:

Jackson uses LinkedHashMap to Serialize/De serialize the entity objects. When I consume the service using parameterized type reference, it works fine.


ResponseEntity<List> response = restTemplate.exchange(
"http://localhost:8080/api/v1/employees" ,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List>(){});
List EmployeeList = response.getBody();