Spring Boot AJAX jQuery to check User Availability Instantly

Introduction

Here in this tutorial I am going to show you how to use AJAX technique using jQuery with Spring Boot application to check user availability instantly without refreshing the web page. I am going to use Thymeleaf template in Spring Boot application. I will use Spring REST to create REST API endpoint which will be called from jQuery code.

Consider a situation when a user filling a long sign up form where the user already input the username and when submits the form then unexpectedly user gets error message “Username already taken” or similar error message. And the user may get irritated because some of the input fields in the sign up form might have been reset to empty, specially password and confirm password fields.

To avoid such situation if you give instant result to the user for username availability then sometimes it makes more sensible than while pressing the submit button and goes top of the signup form to rectify the username input field if input username is not available.

Related Posts:

This example uses JavaScript event on input event for checking user availability.

spring boot ajax jquery

Prerequisites

Spring Boot 2.5.0, Maven 3.6.3, Java at least 8, MySQL 8.0.22

Project Setup

I am creating a maven based project here and you can use any IDE or tool for creating such project. The name of the project I have given for this example is spring-boot-thymeleaf-ajax-username-availability.

The pom.xml file with required dependencies is given below.

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>spring-boot-thymeleaf-ajax-username-availability</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>12</maven.compiler.source>
		<maven.compiler.target>12</maven.compiler.target>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.0</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

		<!--required only if jdk 9 or higher version is used -->
		<dependency>
			<groupId>javax.xml.bind</groupId>
			<artifactId>jaxb-api</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

MySQL Table

I am creating a table called user in MySQL server under roytuts database. I am also dumping two rows data in the table to test the application right away.

CREATE TABLE user (
    id int unsigned COLLATE utf8mb4_unicode_ci NOT NULL AUTO_INCREMENT,
	user_name varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
    PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

insert into `user`(`id`,`user_name`)
values (1,'user1'), (2,'user2');

Entity Class

The entity class will map to the corresponding table. If you have the same column name and Java class attribute name then you don’t need to specify the @Column annotation on Java class attribute or field. For example, in the below class I have not specified @Column annotation on id field.

@Entity
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@Column(name = "user_name")
	private String userName;

	// getters and setters

}

Repository Interface

Spring Data JPA API provides built-in functions for performing basic CRUD (Create Read Update Delete) operations. You can also create own method inside the Repository interface to fit your requirements.

I am creating my own method findUserByUserName() to find a user for the given user name. I have used Optional because a user could not be found for the given name also.

public interface UserRepository extends JpaRepository<User, Integer> {

	Optional<User> findUserByUserName(final String userName);

}

Service Class

The service class is responsible for performing business logic. Here I am returning either user or throwing an exception if user not found in the database. I am returning the DTO version of the user entity because you should never expose the entity class to clients or end users.

@Service
public class UserService {

	@Autowired
	private UserRepository userRepository;

	public UserDto getUserByUserName(final String userName) {
		Optional<User> user = userRepository.findUserByUserName(userName);

		if (user.isPresent()) {
			return EntityToDtoConverter.convertUserEntityToDto(user.get());
		}

		throw new RuntimeException("No user available for the given user name");
	}

}

REST Controller Class

The REST controller class exposes an endpoint for the REST API that will be consumed by clients. I am using HTTP method POST for this endpoint and the input from client will be passed in the request body..

@RestController
public class UserRestController {

	@Autowired
	private UserService userService;

	@PostMapping("/user")
	public ResponseEntity<UserDto> getUserByUserName(@RequestBody UserInput userInput) {
		UserDto userDto = userService.getUserByUserName(userInput.getUserName());

		return new ResponseEntity<UserDto>(userDto, HttpStatus.OK);
	}

}

Main Class

A class with main method having @SpringBootApplication is enough to start the application up and running in embedded Tomcat server.

@SpringBootApplication
public class SpringAjaxUsernameAvailabilityApp {

	public static void main(String[] args) {
		SpringApplication.run(SpringAjaxUsernameAvailabilityApp.class, args);
	}

}

UI – index.html

So far I have finished coding for server side. Now I am going to write code for client side. I am using Thymeleaf template in this Spring Boot application. So I am going to create index.html file under src/main/rsources/templates folder. As I have created index.html file so I don’t need to create any Spring controller class for mapping the URL with this file. The index.html file will automatically be called on request of the root URL for the application.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot MySQL Thymeleaf AJAX - Check Username
	Availability</title>
</head>
<body>
	<div style="margin:10px auto; width: 600px">
		<h3>Spring Boot Thymeleaf, MySQL, AJAX - Username Availability
			Check</h3>
		<div style="padding: 10px;">
			<fieldset>
				<legend>Check Username Availability</legend>
				<div>
					<label>Username</label><br /> <input type="text" name="username"
						id="username" />
					<div id="msg"></div>
				</div>
			</fieldset>
		</div>
	</div>
	
	<script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
	<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" crossorigin="anonymous"></script>
	
	<script type="text/javascript">
		$(document).ready(function() {
			$("#username").on("input", function(e) {
				$('#msg').hide();
				if ($('#username').val() == null || $('#username').val() == "") {
					$('#msg').show();
					$("#msg").html("Username is a required field.").css("color", "red");
				} else {
					$.ajax({
						type: 'post',
						url: "/user",
						data: JSON.stringify({userName: $('#username').val()}),
						contentType: 'application/json; charset=utf-8',
						//dataType: 'html',
						cache: false,
						beforeSend: function (f) {
							$('#msg').show();
							$('#msg').html('Checking...');
						},
						statusCode: {
						    500: function(xhr) {
						    	$('#msg').show();
						    	$("#msg").html("Username available").css("color", "green");
						    }
						},
						success: function(msg) {
							$('#msg').show();
							if(msg !== null || msg !== "") {
								$("#msg").html("Username already taken").css("color", "red");
							} else {
								$("#msg").html("Username available").css("color", "green");
							}
						},
						error: function(jqXHR, textStatus, errorThrown) {
							$('#msg').show();
							$("#msg").html(textStatus + " " + errorThrown).css("color", "red");
						}
					});
				}
			});
		});
	</script>
</body>
</html>

In the above HTML file I have created an input field where user is going to write something and will get instant message whether the value exists in server side (in the database) or not. I am using input event to determine the availability of the input value. I am using CDN (Content Delivery Network) link for jQuery.

As the Spring Boot REST application is decoupled from any UI (User Framework), so you can use any UI framework or simple HTML to consume the REST endpoint.

Testing the Application

Once you run the main class, your application will be running on default port 8080 at localhost.

When you access the URL http://localhost:8080 you will see the following page:

spring boot ajax jquery

As you type something in the input field it will show you whether the user name already taken by someone else or available for you.

spring boot ajax jquery
spring boot ajax jquery

That’s all about how to use AJAX with Spring Boot application for checking user name availability.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *