Account activation by sending email confirmation with Java Spring MVC
Tags: java, spring
Published: 2023-01-05 11:40:51

---
title: Account activation by sending email confirmation with Java Spring MVC
published: true
date: 2018-08-20 19:48:13 UTC
tags: java,spring
canonical_url: 
---

![](https://cdn-images-1.medium.com/max/1024/1*TYt5TmOPN1236zCLHbvfcw.png)

In this article, you will learn how to implement user registration with email confirmation. Basically, after the registration process, a new user is created behind the scenes. But the user cannot log into the application as the account is by default locked. To activate the user account we need a confirmation from the user. That is why we send a link to verify the registration process and activate the user account if the user clicks on the link.

Assuming that you already know how to register a new user, we are now heading towards the email verification part. (In case you don’t have any idea about how to register a new user, you may have a look at the **GitHub repository** mentioned at the end of this article).

We are going to modify few files that we have already created while implementing the user registration process. Apart from this, we are going to add the following new files to our project.

- **Entity**  — VerificationToken.java
- **Repository layers ** — TokenDAO.java, ITokenDAO.java
- **Package**  — event
- **event** \> **Event**  — OnRegistrationSuccessEvent.java
- **event** \> **EventListener**  — RegistrationEmailListener.java

First we are going to start with our **AccountController.java**. The user fills the registration form and clicks submit. Onsubmit, the **User** object with the data is posted to the _registerNewUser_ method with the following method signature.

_AccountController.java_

```
public String registerNewUser(@ModelAttribute(“user”) UserDTO userDto, BindingResult result, WebRequest request, Model model) { … }
```

**Note** : Please ensure that you give the parameters in the same order as above. Changing this order may give you some unwanted errors.

Always make sure that you _do not use your entity directly on your controller_ as it may put your application into security vulnerabilities. (i.e., _you may expose the entire domain model to the client_. We really don’t want this to happen). So make use of a **Data Transfer Object (DTO)** as a middle layer to acces the entity.

We recall few steps from the registration process here,

- Initialize a new User object.
- Find that the user already exists.
- If user already exists, we show an error message else we create a new user and assign the user to the newly initialized User object

_AccountController.java_

```
User registeredUser = new User();

String userName = userDto.getUserName();

if (result.hasErrors()) {

return “registration”;

}

registeredUser = service.findByUsername(userName);

if(registeredUser!=null) {

model.addAttribute(“error”,”There is already an account with this username: “ + userName);

return “registration”;

}

registeredUser = service.registerUser(userDto);
```

Now let’s move into the confirmation of user via email.

Before going to the controller code, we have to first create the **Event** and **EventListener** in order to send the email on successful registration of the user.

This will be our event,

_OnRegistrationSuccessEvent.java_

```
public class OnRegistrationSuccessEvent extends ApplicationEvent {

private static final long serialVersionUID = 1L;

private String appUrl;

private User user;

public OnRegistrationSuccessEvent(User user, String appUrl) {

super(user);

this.user = user;

this.appUrl = appUrl;

}

public String getAppUrl() {

return appUrl;

}

public void setAppUrl(String appUrl) {

this.appUrl = appUrl;

}

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}
```

Events must always inherit the **ApplicationEvent** class of Spring that is inherited from the **java.util.EventObject**. We have three variables _serialVersionUID, appurl and user_.

> It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, otherwise it may result in unexpected InvalidClassExceptions during deserialization. To know more visit the **Java docs** for [**java.io.Serializable**](https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html)

appurl is the context path to our application and user is the new user object. These two variables construct the confirmation url. However, we do not use the serialVersionUID in our url. And finish the Event creation with the implementation of the basic _getters/setters_ and _constructors_.

Next is we have to build an **EventListener** to handle the _OnRegistrationSuccessEvent_. We name our EventListener as RegistrationEmailListener.java and give it the @Component annotation. This will be responsible for sending our confirmation email to the newly registered user. The **RegistrationEmailListener** _inherits_ the **ApplicationListener** that Listens to our _OnRegistrationSuccessEvent_ event.

```
@Component

public class RegistrationEmailListener implements ApplicationListener\<OnRegistrationSuccessEvent\> { … }
```

Inside this class, we will do the **Dependency Injection** for the **IUserService** and **MailSender** with the @Autowired annotaion of  **Spring**.

```
@Autowired

private IUserService userService;

@Autowired

private MailSender mailSender;
```

Then we will override **onApplicationEvent** , the method defined by the org.springframework.context.ApplicationListener. Inside this we are going to call the _confirmRegistration_ method that we will create in the next few steps.

```
@Override

public void onApplicationEvent(OnRegistrationSuccessEvent event) {

this.confirmRegistration(event);

}
```

The _confirmRegistration_ method takes **OnRegistrationSuccessEvent** as its parameter.

```
private void confirmRegistration(OnRegistrationSuccessEvent event) { … }
```

Then we will initialize the user with the passed parameter. Each user _must have a unique id_ because at this point we are still unaware that the new user have been already registered. For this, we create a unique token using the **UUID**. Using this UUID, we are going to create a **verification token** along with an **expiration date** and save it to the _VerificationToken_ table in the database. When the user clicks the link, the verification token helps us to identify whether the confirmation link is valid and is not expired. We create this token in the _createVerificationToken_ method implemented in the UserService.

_RegistrationEmailListener.java_

```
User user = event.getUser();

String token = UUID.randomUUID().toString();

userService.createVerificationToken(user,token);
```

_IUserService.java_

```
public void createVerificationToken(User user, String token);
```

_UserService.java_

```
@Override 
public void createVerificationToken(User user, String token) { VerificationToken newUserToken = new VerificationToken(token, user); tokenDAO.save(newUserToken); 
}
```

After saving the verification token, we will now generate the confirmation email that has to be sent to the user. Get the _recipient_ from the user object. Then set the email subject text to whatever you want. But I recommend you to _give a subject related to the email message_. (i.e., Registration Confirmation.) Then we create the url by concatenating the appurl with the route to the method that activates the user and with the user token (i.e., **UUID** ). We will then generate the message to be sent along with the email.

```
String recipient = user.getEmail();

String subject = “Registration Confirmation”;

String url

= event.getAppUrl() + “/confirmRegistration?token=” + token;

String message = “Thank you for registering. Please click on the below link to activate your account.”;
```

Now we have all the necessary data and we are going to send the email using the SimpleMailMessage.

```
SimpleMailMessage email = new SimpleMailMessage();

email.setTo(recipient);

email.setSubject(subject);

email.setText(message + “http://localhost:8080" + url);

mailSender.send(email);
```

Create the **SimpleMailMessage** bean and set the **SMTP** mail settings in the _Config.java_ file.

```
@Bean(name = “mailSender”)

public MailSender javaMailService() {

JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

javaMailSender.setHost(“smtp.gmail.com”);

javaMailSender.setPort(587);

javaMailSender.setProtocol(“smtp”);

javaMailSender.setUsername(“sender’s email”);

javaMailSender.setPassword(“sender’s password”);

Properties mailProperties = new Properties();

mailProperties.put(“mail.smtp.auth”, “true”);

mailProperties.put(“mail.smtp.starttls.enable”, “true”);

mailProperties.put(“mail.smtp.debug”, “true”);

javaMailSender.setJavaMailProperties(mailProperties);

return javaMailSender;

}

@Bean

public MessageSource messageSource() {

final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();

messageSource.setBasename(“classpath:messages”);

messageSource.setUseCodeAsDefaultMessage(true);

messageSource.setDefaultEncoding(“UTF-8”);

messageSource.setCacheSeconds(0);

return messageSource;

}
```

Now we have to create the VerificationToken Entity inside the entity package of your application.

_VerificationToken.java_

```
@Entity

@Table(name = “verification\_token”)

public class VerificationToken {

private static final int EXPIRATION = 60 \* 24;

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private int id;

@Column(name=”token”)

private String token;

@OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)

@JoinColumn(name = “user\_id”, nullable = false)

private User user;

@Column(name=”created\_date”)

private Date createdDate;

@Column(name=”expiry\_date”)

private Date expiryDate;
```

Generate the basic _getters/setters_ and the _constructors_ for the entity. We will create the **calculateExpiryDate** method to calculate the expiration date of the verification token.

_VerificationToken.java_

```
private Date calculateExpiryDate(int expiryTimeInMinutes) {

Calendar calendar = Calendar.getInstance();

calendar.setTime(new Timestamp(calendar.getTime().getTime()));

calendar.add(Calendar.MINUTE, expiryTimeInMinutes);

return new Date(calendar.getTime().getTime());

}
```

Then we are going to initiate the **publishEvent** in order to send the email to the user. After the email has successfully sent, the user will receive a success message.

_AccountController.java_

```
try {

String appUrl = request.getContextPath();

eventPublisher.publishEvent(new OnRegistrationSuccessEvent(registeredUser, appUrl));

}catch(Exception re) {

re.printStackTrace();

}

return “registrationSuccess”;
```

The user receives an email with the following format,

**Thank you for registering. Please click on the below link to activate your account.** [**http://localhost:8080/spring-email-verification/confirmRegistration?token=3e5a64c7-dbb1-4179-be48-be9361703457**](http://localhost:8080/spring-email-verification/confirmRegistration?token=3e5a64c7-dbb1-4179-be48-be9361703457)

#### After the user clicks the link:

Now when the user clicks the link, he/she gets directed to the path /confirmRegistration .

_AccountController.java_

```
@GetMapping("/confirmRegistration")

public String confirmRegistration(WebRequest request, Model model,@RequestParam("token") String token) {

VerificationToken verificationToken = service.getVerificationToken(token); 
 if(verificationToken == null) { 
 String message = messages.getMessage("auth.message.invalidToken", null, locale); 
 model.addAttribute("message", message); 
 return "redirect:access-denied"; 
 }

User user = verificationToken.getUser(); 
 Calendar calendar = Calendar.getInstance(); 
 if((verificationToken.getExpiryDate().getTime()-calendar.getTime().getTime())\<=0) { 
 String message = messages.getMessage("auth.message.expired", null, locale); 
 model.addAttribute("message", message); 
 return "redirect:access-denied"; 
 }

user.setEnabled(true); 
 service.enableRegisteredUser(user); 
 return null; 
}
```

Here the **GET method** is called and it first checks whether the token is valid. If not valid, we are going to pass an error stating that the link is invalid. Then we will check the expiration of the token. If the link is valid in both the cases, we will activate the user with the setteruser.setEnabled(true).

Finally, in the **UserService** we will update the database with the new values.

_IUserService.java_

```
public void enableRegisteredUser(User user);
```

_UserService.java_

```
@Override 
@Transactional 
public void enableRegisteredUser(User user) { 
 userDAO.save(user); 
}
```

So, we have successfully implemented the user account confirmation process with Spring. You can find the complete code [**in this Github repository**](https://github.com/angelapriyadharshini/spring-email-verification).

Thank you for visiting my blog :)