Oops Java Lab

Object Oriented Programming with Java lab


Experiment 1
Objective: Installation and use Java compiler and eclipse platform to write and execute java program.

Theory:

  • Java is a high-level, object-oriented programming language developed by Sun Microsystems (now owned by Oracle Corporation). It was first released in 1995, designed to be platform-independent. i.e. Java programs can run on any device or operating system that has a Java Virtual Machine (JVM) installed.
  • Java is widely used for developing a variety of applications, including web applications, mobile apps (Android applications are widely built using Java), enterprise software, and more. Java has a vast ecosystem of libraries, framework, and tools that furture ecnhance its capabilities and productivity for developers.

Installation of Java Development Kit (JDK):

  • Java Development Kit (JDK) is essential for Java development as it includes the Java Runtime Environment (JRE), compiler, debugger and other tools necessary for building Java applications.

  • Visit: Official Oracle website or OpenJDK website to download the latest version of JDK. Choose the appropriate JDK version for your operating system (Windows, macOS, Linux).

  • Run the downloaded JDK installer executable file. Ensure that the JDK bin directory is added to the system PATH environment variable.

  • Open a command prompt (Windows) or terminal (macOS, Linux). Type java -version and press Enter to verify the JDK installation.

Terminal
java -version
openjdk version "11.0.16.1" 2022-08-12 LTS
OpenJDK Runtime Environment Microsoft-40648 (build 11.0.16.1+1-LTS)
OpenJDK 64-Bit Server VM Microsoft-40648 (build 11.0.16.1+1-LTS, mixed mode)

Installation of Eclipse IDE:

  • Eclipse is a powerfull IDE widely used by Java developers for coding, debugging, and testing Java applications.

  • Visit: Eclipse Foundation website and navigate to the downloads section. Run the downloaded Eclipse installer executable file and complete the installation process.

Installation of Java with Terminal in Linux:

  • For installing JDK
Terminal
sudo apt-get install default-jdk
java -version
  • For installing Eclipse
Terminal
sudo snap install eclipse --clasic
  • Instructions for creating and running it both in Eclipse and using the command line (cmd).

Here's a simple Java program that checks whether a given number is prime or not.

Prime.java
public class Prime {
	public static void main(String[] args) {
		int num = 29; // Change this number to check prime or not for a different number
		boolean prime = true;
		if (num <= 1) {
			prime = false;
		} else {
			for (int i = 2; i <= num / 2; i++) {
				if (num % i == 0) {
					prime = false;
				}
			}
		}
		if (prime == true) {
			System.out.println(num + " is a prime no.");
		} else {
			System.out.println(num + " is not a prime no.");
		}
	}
}

Running in Eclipse:

  • Open Eclipse and create a new Java project.
  • Inside the project, create a new Java class named Prime.
  • Write the provided Java code into the Prime.java file.
  • Save the file.
  • Right-click on the Prime.java file in the Package Explorer.
  • Select "Run As" -> "Java Application".
  • Now, the output in the console.
Terminal
29 is a prime no.

Here's a simple Java program that calculates the factorial of a given number.

Factorial.java
public class Factorial {
  public static void main(String[] args) {
    int number = 5; // Change this number to calculate factorial for a different number
    long factorial = calculateFactorial(number);
    System.out.println("Factorial of " + number + " is: " + factorial);
  }
 
  public static long calculateFactorial(int n) {
    if (n == 0 || n == 1) {
      return 1;
    } else {
      return n * calculateFactorial(n - 1);
    }
  }
}

Running using CMD:

  • Save the provided Java code into a file named Factorial.java.
  • Open a command prompt (CMD).
  • Navigate to the directory where Factorial.java is saved using the cd command.
  • Compile the Java file by typing javac Factorial.java and pressing Enter.
  • Once compiled successfully, run the program by typing java Factorial and pressing Enter.
  • You should see the output in the command prompt.
Terminal
Factorial of 5 is: 120
Experiment 2
Objective: Creating simple Calculator java programs using command line arguments.

Theory:

  • Command-Line Arguments: Command-line arguments are parameters passed to a program when it is executed. In Java, these arguments are stored in the args parameter of the main method.
  • Parsing: Parsing is the process of converting data from one format to another. Here, we parse string arguments into numerical values using methods like Double.parseDouble().
  • Conditional Statements: The program uses conditional statements (if and switch) to validate input, handle errors, and perform different operations based on the operator.
  • Arithmetic Operations: Arithmetic operations such as addition, subtraction, multiplication, and division are fundamental mathematical concepts. In this program, they are implemented using Java operators (+, -, *, /).
  • Error Handling: Error handling is crucial for robust software. In this program, we handle division by zero by checking for this condition explicitly
Calculator.java
public class Calculator {
  public static void main(String[] args) {
    
    if (args.length != 3) {
      System.out.println("Usage: java Calculator num1 operator num2");
      return;
    }
 
    double num1 = Double.parseDouble(args[0]);
    String operator = args[1];
    double num2 = Double.parseDouble(args[2]);
    double result = 0.0;
 
    switch (operator) {
      case "+":
        result = num1 + num2;
        break;
 
      case "-":
        result = num1 - num2;
        break;
 
      case "*":
        result = num1 * num2;
        break;
 
      case "/":
        if (num2 != 0) {
          result = num1 / num2;
        } else {
          System.out.println("Error: Division by zero");
          return;
        } break;
      default:
        System.out.println("Error: Invalid operator");
        return;
    }
    System.out.println("Result: " + result);
  }
}

To compile this code, open your command prompt or terminal, navigate to the directory where you saved Calculator.java, and run as:

Terminal
javac Calculator.java

Once compiled successfully, run the program with command-line arguments as:

Terminal
java Calculator 5 + 3
Output
Result: 8.0

Similarly, we can perform other operations like subtraction, multiplication and division:

Terminal
java Calculator 10 - 4
java Calculator 6 * 2
java Calculator 8 / 2
Experiment 3
Objective: Understand OOP concepts (Abstraction) and basics of Java programming.

Theory:

  • A class is a blueprint or template for creating objects. It defines the properties (fields) and behaviors (methods) that objects of that type will have.
  • Abstraction is the process of hiding the implementation details and showing only the essential features of an object. Abstract classes and interfaces are used to achieve abstraction.
Abstraction.java
abstract class Car {
  Car() {
    System.out.println("Car is built. ");
  }
  abstract void drive();
 
  void gearChange() {
    System.out.println("Gearchanged!!");
  }
}
 
class Tesla extends Car {
  void drive() {
    System.out.println("Drive Safely");
  }
}
 
class Abstraction {
  public static void main(String args[]) {
    Car obj = new Tesla();
    obj.drive();
    obj.gearChange();
  }
}
Output
Car is built. 
Drive Safely
Gearchanged!!
Experiment 4
Objective: Create Java programs using inheritance and polymorphism.

Theory:

  • Inheritance is a mechanism by which a new class (called a subclass or derived class) is created from an existing class (called a superclass or base class). The subclass inherits the properties and behaviors (methods) of the superclass. This allows for code reuse and peromotes the creation of hirerchical relationships between classes.

  • polymorphism is Java refers to the ability of objects to take on multiple forms. It allows objects of different classes to be treated as objects of a common superclass through a common interface.

There are two types of polymorphism in java-

  • Compile-time polymorphism (method overloading)
  • Runtime polymorphism (method overriding)
Inheritance.java
// Superclass
class Animal {
  void eat() {
    System.out.println("I am a omnivorous!! ");
  }
}
 
// Subclass
class Mammal extends Animal {
  void nature() {
    System.out.println("I am a mammal!! ");
  }
}
 
class Dog extends Mammal {
  void sound() {
    System.out.println("I bark!! ");
  }
}
 
class Inheritance {
  public static void main(String args[]) {
    Dog d = new Dog();
    d.eat();
    d.nature();
    d.sound();
  }
}
Output
I am a omnivorous!! 
I am a mammal!!
I bark!!

Compile-time polymorphism (Method Overloading): This occurs when multiple methods in a class have the same name but different parameters.

Overloading.java
class CircleArea {
  double area(double x) {
    return 3.14 * x;
  }
}
 
class SquareArea {
  int area(int x) {
    return x * x;
  }
}
 
class RectangleArea {
  int area(int x, int y) {
    return x * y;
  }
}
 
class TriangleArea {
  int area(int y, int x) {
    return (y * x) / 2;
  }
}
 
class Overloading {
  public static void main(String args[]) {
    CircleArea ca = new CircleArea();
    SquareArea sa = new SquareArea();
    RectangleArea ra = new RectangleArea();
    TriangleArea ta = new TriangleArea();
 
    System.out.println("Circle area = " + ca.area(1));
    System.out.println("Square area = " + sa.area(2));
    System.out.println("Rectangle area = " + ra.area(3, 4));
    System.out.println("Triangle area = " + ta.area(6, 3));
  }
}
Output
Circle area = 3.14
Square area = 4
Rectangle area = 12
Triangle area = 9

Runtime polymorphism (Method Overriding): This occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. The subclass method must have the same signature (name and parameters) as the superclass method.

Overriding.java
 class Shape {
  void draw() {
    System.out.println("Mention shape here");
  }
 
  void numberOfSides() {
    System.out.println("side = 0");
  }
}
 
class Circle extends Shape {
  void draw() {
    System.out.println("CIRCLE ");
  }
 
  void numberOfSides() {
    System.out.println("side = 0 ");
  }
}
 
class Box extends Shape {
  void draw() {
    System.out.println("BOX ");
  }
 
  void numberOfSides() {
    System.out.println("side= 6");
  }
}
 
class Triangle extends Shape {
  void draw() {
    System.out.println("TRIANGLE ");
  }
 
  void numberOfSides() {
    System.out.println("side = 3 ");
  }
}
 
public class Overriding {
  public static void main(String args[]) {
    Circle c = new Circle();
    c.draw();
    c.numberOfSides();
 
    Box b = new Box();
    b.draw();
    b.numberOfSides();
 
    Triangle t = new Triangle();
    t.draw();
    t.numberOfSides();
  }
}
Output
CIRCLE 
side = 0
BOX
side= 6
TRIANGLE
side = 3
 

Experiment 5
Objective: Implement error-handling techniques using exception handling and multithreading.
Theory:
Exception handling and multithreading are two crucial aspects of Java programming, especially when it comes to building robust and efficient applications.

ExceptionDemo.java
public class ExceptionDemo {
  public static void main(String[] args) {
      // array of size 4.
      int[] arr = new int[4];
 
      try {
          int i = arr[4];
 
          // this statement will never execute
          // as exception is raised by above statement
          System.out.println("Inside try block");
      }
 
      catch (ArrayIndexOutOfBoundsException ex) {
          System.out.println("Exception caught in catch block");
      }
      
      // this will always execute 
      finally {
          System.out.println("finally block executed");
      }
      // rest program will be executed
      System.out.println("Outside try-catch-finally clause");
  }
}
Output
Exception caught in catch block
finally block executed
Outside try-catch-finally clause 
  • Throw Exception
ThrowExcepDemo.java
public class ThrowExcepDemo {
    static void fun() {
        try {
            throw new NullPointerException("demo");
        } catch (NullPointerException e) {
            System.out.println("Caught inside fun().");
            throw e; // rethrowing the exception
        }
    }
 
    public static void main(String args[]) {
        try {
            fun();
        } catch (NullPointerException e) {
            System.out.println("Caught in main.");
        }
    }
}
Caught inside fun().
Caught in main.
  • Throws Exception
ThrowsExcepDemo.java
public class ThrowsExecpDemo {
    static void fun() throws IllegalAccessException {
        System.out.println("Inside fun(). ");
        throw new IllegalAccessException("demo");
    }
 
    public static void main(String args[]) {
        try {
            fun();
        } catch (IllegalAccessException e) {
            System.out.println("caught in main.");
        }
    }
}
Output
Inside fun(). 
caught in main.

Thread States

  • New: The thread is created but not yet started.
  • Runnable: The thread is ready to run and waiting for CPU time.
  • Blocked: The thread is waiting for a monitor lock to enter a synchronized block or method.
  • Waiting: The thread is waiting indefinitely for another thread to perform a particluar action.
  • Time Waiting: The thread is waiting for a specified period.
  • Terminated: The thread has finished execution.
ThreadStateDemo.java
class ThreadTest implements Runnable {
  public void run() {
 
    // try-catch block
    try {
      // moving thread t2 to the state timed waiting
      Thread.sleep(100);
    } catch (InterruptedException ie) {
      ie.printStackTrace();
    }
 
    System.out.println(
        "The state of thread t1 while it invoked the method join() on thread t2 -" + 
            ThreadStateDemo.t1.getState());
 
    // try-catch block
    try {
      Thread.sleep(200);
    } catch (InterruptedException ie) {
      ie.printStackTrace();
    }
  }
}
 
// ThreadState class implements the interface Runnable
public class ThreadStateDemo implements Runnable {
  public static Thread t1;
  public static ThreadStateDemo obj;
 
  // main method
  public static void main(String args[]) {
    // creating an object of the class ThreadState
    obj = new ThreadStateDemo();
    t1 = new Thread(obj);
 
    // thread t1 is spawned
    // The thread t1 is currently in the NEW state.
    System.out.println("The state of thread t1 after spawning it - " + t1.getState());
 
    // invoking the start() method on
    // the thread t1
    t1.start();
 
    // thread t1 is moved to the Runnable state
    System.out.println(
        "The state of thread t1 after invoking the method start() on it - " + t1.getState());
  }
 
  public void run() {
    ThreadTest myObj = new ThreadTest();
    Thread t2 = new Thread(myObj);
 
    // thread t2 is created and is currently in the NEW state.
    System.out.println("The state of thread t2 after spawning it - " + t2.getState());
    t2.start();
 
    // thread t2 is moved to the runnable state
    System.out.println(
        "the state of thread t2 after calling the method start() on it - " + t2.getState());
 
    // try-catch block for the smooth flow of the program
    try {
      // moving the thread t1 to the state timed waiting
      Thread.sleep(200);
    } catch (InterruptedException ie) {
      ie.printStackTrace();
    }
 
    System.out.println(
        "The state of thread t2 after invoking the method sleep() on it - " + t2.getState());
 
    // try-catch block for the smooth flow of the program
    try {
      // waiting for thread t2 to complete its execution
      t2.join();
    } catch (InterruptedException ie) {
      ie.printStackTrace();
    }
    System.out.println(
        "The state of thread t2 when it has completed it's execution - " + t2.getState());
  }
}
Output
The state of thread t1 after spawning it - NEW
The state of thread t1 after invoking the method start() on it - RUNNABLE
The state of thread t2 after spawning it - NEW
the state of thread t2 after calling the method start() on it - RUNNABLE
The state of thread t1 while it invoked the method join() on thread t2 -TIMED_WAITING
The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING
The state of thread t2 when it has completed it's execution - TERMINATED
Experiment 6
Objective: Create java program with the use of java packages.

Theory:
A package in Java is a way to organize classes and interfaces into namespaces, facilitating code organization and managment.

PackageDemo.java
package MyPack;
 
// Class to which the above package belongs
public class PackageDemo {
 
    // Member functions of the class- 'Demo'
    // Method 1 - To show()
    public void show() {
 
        // Print message
        System.out.println("Hi Everyone");
    }
 
    // Method 2 - To show()
    public void view() {
        // Print message
        System.out.println("Hello");
    }
}

Type this code in terminal for create directory for package. the folder will create same as Package name MyPack. In the MyPack folder .class file will create with the name .java file.

Terminal
javac -d . PackageDemo.java
PackageImportDemo.java
package MyPack;
 
import MyPack.*;
 
// Class to which the package belongs
public class PackageImportDemo {
 
    // main driver method
    public static void main(String arg[]) {
 
        // Creating an object of Demo class
        PackageDemo d = new PackageDemo();
 
        // Calling the functions show() and view()
        // using the object of Demo class
        d.show();
        d.view();
    }
}

This line of code will folow rule same as above. If we choose another name of package then .class file will create in new folder.

Terminal
javac -d . PackageImportDemo.java

For run this code we need to type package name with .class file name.

Terminal
java MyPack.PackageImportDemo
Output
Hi Everyone
Hello
Experiment 7
Objective: Construct java program using Java I/O package.

Theory:
File Input/Output (I/O) in Java is managed through the Java I/O package java.io. This package provides classes and interfaces for reading and eriting data to files.

Copy File Demo

First we need to create the .txt file with the name input. Write something in input.txt file.

CopyFile.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class CopyFile {
 
   public static void main(String args[]) throws IOException {
      FileInputStream in = null;
      FileOutputStream out = null;
 
      try {
         in = new FileInputStream("input.txt");
         out = new FileOutputStream("output.txt");
 
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      } finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}
  • The new file will be create and copy all the text which is written in input.txt.

Same Here, First we need to create the .txt file with the name input. Write something in input.txt file.

FileCopyDemo.java
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class FileCopyDemo {
 
   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;
 
      try {
         in = new FileReader("input.txt");
         out = new FileWriter("output.txt");
 
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      } finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}
  • The output will be showing as creating or coping all the text from input.txt to output.txt.

File Output Stream

FileOutputStreamExample.java
import java.io.*;
 
public class FileOutputStreamExample {
      public static void main(String args[]) {
            try {
                  FileOutputStream fout = new FileOutputStream("D:\\testout.txt");
                  fout.write(65);
                  fout.write(66);
                  fout.close();
                  System.out.println("success...");
            } catch (Exception e) {
                  System.out.println(e);
            }
      }
}
  • The testout.txt file will be created in D drive of your computer system storage. In the testout file text will appear as AB.
Output
success...
FileOutputStreamExample1.java
import java.io.FileOutputStream;
 
public class FileOutputStreamExample1 {
    public static void main(String args[]) {
        try {
            FileOutputStream fout = new FileOutputStream("testout.txt");
            String s = "Welcome to javaTpoint.";
            byte b[] = s.getBytes();// converting string into byte array
            fout.write(b);
            fout.close();
            System.out.println("success...");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
  • The testout.txt file will be Created in that folder where we execute this code.
testout.txt
Welcome to javaTpoint.
Output
success...
Experiment 8
Objective: Create industry oriented application using Spring Framework. (User Registration and Login Form)

Theory:

  • Spring Security is a framework that provides authentication, authorization, and protection against common attacks. With first-class support for securing imperative and reactive applications, it is the de-facto standard for securing Spring-based applications.

Tools and Technologies used:

  • Spring Boot 3
  • Spring MVC 6
  • Spring Secutrity 6
  • Hibernate 6
  • Thymeleaf 3
  • MySQL 8
  • Maven

Create a Spring Boot Project: Spring Boot provides a web tool called Spring Initializer to quickly bootstrap an application. To use it, go to https://start.spring.io and generate a new Spring Boot Project.
Use the below details in the Spring boot creation:

  • Generate: Maven Project
  • Java Version: 17
  • Spring Boot: 3.3.1
  • Group: net.guides.springboot
  • Arifect: registration-login-demo
  • Name: registration-login-demo
  • Dependencies: Spring Web, Spring Data JPA, MySQL Driver, Thymeleaf, Devtools, Security, Lombok
  • Click on the generate project button. Next, you can extract and import the downloaded ZIP file into your favorite IDE.
Project Structure

Project Structure

Create the file and packages add these code

UserAuth/pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.Springboot</groupId>
  <artifactId>UserAuth</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>UserAuth</name>
  <description>Demo project for Spring Boot</description>
  <properties>
    <java.version>17</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-springsecurity6</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project> 
src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://localhost:3305/mysql?useSSL=false 
spring.datasource.username=root 
spring.datasource.password=system 
 
#hibernate ddl auto (create , create-drop, validate, update) 
spring.jpa.hibernate.ddl-auto=update 
 
#Display Application warn and errors and info 
logging.level.org.hibernate.SQL=DEBUG 
logging.level.org.hibernate.Type=TRACE 
src/main/java/com.Springboot.UserAuth.Entity/User.java
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
 
@Entity
@Table(name = "users")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  // @Column(unique = true)
  private String username;
  private String password;
  private String fullname;
 
  public User() {
 
  }
 
  public User(String username, String password, String fullname) {
    super();
    this.username = username;
    this.password = password;
    this.fullname = fullname;
  }
 
  public Long getId() {
    return id;
  }
 
  public void setId(Long id) {
    this.id = id;
  }
 
  public String getUsername() {
    return username;
  }
 
  public void setUsername(String username) {
    this.username = username;
  }
 
  public String getPassword() {
    return password;
  }
 
  public void setPassword(String password) {
    this.password = password;
  }
 
  public String getFullname() {
    return fullname;
  }
 
  public void setFullname(String fullname) {
    this.fullname = fullname;
  }
 
  @Override
  public String toString() {
    return "User [id=" + id + ", username=" + username + ", password=" +
        password + ", fullname=" + fullname + "]";
  }
}
src/main/java/com.Springboot.UserAuth.repositories/UserRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.dto.UserDto;
 
public interface UserRepository extends JpaRepository<User, Long> {
 
  User findByUsername(String username);
 
  User save(UserDto userDto);
}
src/main/java/com.Springboot.UserAuth.dto/UserDto.java
public class UserDto {
  private String username;
  private String password;
  private String fullname;
 
  public UserDto(String username, String password, String fullname) {
    super();
    this.username = username;
    this.password = password;
    this.fullname = fullname;
  }
 
  public String getUsername() {
    return username;
  }
 
  public void setUsername(String username) {
    this.username = username;
  }
 
  public String getPassword() {
    return password;
  }
 
  public void setPassword(String password) {
    this.password = password;
  }
 
  public String getFullname() {
    return fullname;
  }
 
  public void setFullname(String fullname) {
    this.fullname = fullname;
  }
 
  @Override 
  public String toString() { 
   return "UserDto [username=" + username + ", password=" + password + ", 
     fullname=" + fullname + "]"; 
  }
}
src/main/java/com.Springboot.UserAuth.Services/UserService.java
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.dto.UserDto;
 
public interface UserService {
  User findByUsername(String username);
 
  User save(UserDto userDto);
} 
src/main/java/com.Springboot.UserAuth.Services/UserServiceImpl.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
 
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.dto.UserDto;
import com.Springboot.UserAuth.repositories.UserRepository;
 
@Service
public class UserServiceImpl implements UserService {
 
  @Autowired
  PasswordEncoder passwordEncoder;
 
  private UserRepository userRepository;
 
  public UserServiceImpl(UserRepository userRepository) {
    super();
    this.userRepository = userRepository;
  }
 
  @Override
  public User findByUsername(String username) {
    return userRepository.findByUsername(username);
  }
 
  @Override
  public User save(UserDto userDto) {
    User user = new User(userDto.getUsername(),
        passwordEncoder.encode(userDto.getPassword()),
        userDto.getFullname());
    return userRepository.save(user);
  }
}
src/main/java/com.Springboot.UserAuth.Configuration/CustomUserDetails.java
import java.util.Collection;
 
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
 
public class CustomUserDetails implements UserDetails {
 
  private String username;
  private String password;
  private Collection<? extends GrantedAuthority> authorities;
  private String fullname;
 
  public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities,
      String fullname) {
    this.username = username;
    this.password = password;
    this.authorities = authorities;
    this.fullname = fullname;
  }
 
  public String getFullname() {
    return fullname;
  }
 
  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    return authorities;
  }
 
  @Override
  public String getPassword() {
    return password;
  }
 
  @Override
  public String getUsername() {
    return username;
  }
 
  @Override
  public boolean isAccountNonExpired() {
    return true;
  }
 
  @Override
  public boolean isAccountNonLocked() {
    return true;
  }
 
  @Override
  public boolean isCredentialsNonExpired() {
    return true;
  }
 
  @Override
  public boolean isEnabled() {
    return true;
  }
}
src/main/java/com.Springboot.UserAuth.Configuration/CustomUserDetailsService.java
import java.util.Arrays;
import java.util.Collection;
 
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
 
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.repositories.UserRepository;
 
@Service
public class CustomUserDetailsService implements UserDetailsService {
 
  private UserRepository userRepository;
 
  public CustomUserDetailsService(UserRepository userRepository) {
    super();
    this.userRepository = userRepository;
  }
 
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 
    User user = userRepository.findByUsername(username);
    if (user == null) {
      throw new UsernameNotFoundException("Username or Password not found");
    }
    return new CustomUserDetails(user.getUsername(), user.getPassword(),
        authorities(), user.getFullname());
  }
 
  public Collection<? extends GrantedAuthority> authorities() {
    return Arrays.asList(new SimpleGrantedAuthority("USER"));
  }
}
src/main/java/com.Springboot.UserAuth.Configuration/SecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 
@Configuration
@EnableWebSecurity
public class SecurityConfig {
 
  @Autowired
  CustomUserDetailsService customUserDetailsService;
 
  @Bean
  public static PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
 
  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
    http.csrf().disable().authorizeHttpRequests().requestMatchers("/register")
        .permitAll().requestMatchers("home").permitAll().and().formLogin().loginPage("/login")
        .loginProcessingUrl("/login").defaultSuccessUrl("/home", true).permitAll().and().logout()
        .invalidateHttpSession(true).clearAuthentication(true)
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout")
        .permitAll();
 
    return http.build();
  }
 
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
  }
}
src/main/java/com.Springboot.UserAuth.Controller/UserController.java
import java.security.Principal;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
 
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.Services.UserService;
import com.Springboot.UserAuth.dto.UserDto;
 
@Controller
public class UserController {
 
  @Autowired
  private UserDetailsService userDetailsService;
 
  private UserService userService;
 
  public UserController(UserService userService) {
    this.userService = userService;
  }
 
  @GetMapping("/home")
  public String home(Model model, Principal principal) {
    UserDetails userDetails = userDetailsService.loadUserByUsername(principal.getName());
    model.addAttribute("userdetail", userDetails);
    return "home";
  }
 
  @GetMapping("/login")
  public String login(Model model, UserDto userDto) {
 
    model.addAttribute("user", userDto);
    return "login";
  }
 
  @GetMapping("/register")
  public String register(Model model, UserDto userDto) {
    model.addAttribute("user", userDto);
    return "register";
  }
 
  @PostMapping("/register")
  public String registerSava(@ModelAttribute("user") UserDto userDto, Model model) {
    User user = userService.findByUsername(userDto.getUsername());
    if (user != null) {
      model.addAttribute("Userexist", user);
      return "register";
    }
    userService.save(userDto);
    return "redirect:/register?success";
  }
}
src/main/resources/templates/home.html
<!DOCTYPE html>
<html>
 
<head>
  <meta charset="UTF-8">
  <title>Home Page</title>
  <style>
    body {
      background-color: #f5f5f5;
      margin: 0;
      padding: 0;
    }
 
    .dashboard {
      background-color: #5e057e;
      color: #fff;
      padding: 40px;
      text-align: center;
    }
 
    .dashboard_title {
      font-size: 24px;
      margin-top: 0;
    }
 
    .dashboard_user {
      margin-top: 20px;
    }
 
    .dashboard_user_name {
      font-size: 18px;
      color: #c299d0;
    }
 
    .span-text {
      text-align: right;
      color: black;
    }
  </style>
</head>
 
<body>
  <div class="dashboard">
    <h1 class="dashboard_title">Welcome to the Dashboard </h1>
    <div class="dashboard_user">
      <h2 th:text="${userdetail.fullname}" class="dashboard_user_name"></h2>
    </div>
    <div class="span-text">
      <span sec:authorize="isAuthenticated" style="color: white;">
        <a th:href="@{/logout}">Logout</a>
      </span>
    </div>
  </div>
 
</body>
 
</html>
src/main/resources/templates/register.html
<!DOCTYPE html>
<html>
 
<head>
  <meta charset="UTF-8">
  <title>Registration</title>
  <style>
    body {
      font-family: 'Arial', sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f4f4f4;
    }
 
    .form-container {
      background-color: #fff;
      width: 400px;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }
 
    h2 {
      color: #5e057e;
      text-align: center;
      margin-bottom: 20px;
    }
 
    label {
      display: block;
      margin-bottom: 8px;
      color: #5e057e;
    }
 
    input {
      width: 100%;
      padding: 8px;
      margin-bottom: 16px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
    }
 
    button {
      background-color: #5e057e;
      color: #fff;
      padding: 10px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-weight: bold;
      transition: background-color 0.3s;
    }
 
    button:hover {
      background-color: #299d00;
    }
 
    .form-footer {
      text-align: center;
      margin-top: 20px;
      color: #888;
    }
 
    .success-message {
      background-color: #5e057e;
      color: #fff;
      padding: 10px;
      border-radius: 3px;
      text-align: center;
    }
  </style>
</head>
 
<body>
  <div class="form-container">
 
    <div th:if="${param.success}">
      <div class="success-message">
        <p>Registration Successful!</p>
      </div>
    </div>
 
    <h2>Registration</h2>
    <form th:action="@{/register}" method="post" role="form" th:object="${user}">
      <label for="fullname">FullName:</label>
      <input th:field="*{fullname}" type="text" id="fullname" name="fullname" 
        placeholder="Enter your FullName" required>
 
      <label for="username">Username:</label>
      <input th:field="*{username}" type="text" id="username" name="username" 
        placeholder="Enter your Username" required>
 
      <label for="password">Password:</label>
      <input th:field="*{password}" type="password" id="password" name="password" 
        placeholder="Enter your Password" required>
 
      <button type="submit">Register</button>
    </form>
    <div>
      <span th:if="${Userexist}" style="color: red;">Username is Taken</span>
    </div>
    <div>
      <span class="form-footer">Already have an account? 
        <a th:href="@{/login1}">Login</a>here.
      </span>
    </div>
  </div>
</body>
 
</html>
src/main/resources/templates/login.html
<!DOCTYPE html>
<html>
 
<head>
  <meta charset="UTF-8">
  <title>Login</title>
  <style>
    body {
      font-family: 'Arial', sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f4f4f4;
    }
 
    .form-container {
      background-color: #fff;
      width: 400px;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }
 
    h2 {
      color: #5e057e;
      text-align: center;
      margin-bottom: 20px;
    }
 
    label {
      display: block;
      margin-bottom: 8px;
      color: #5e057e;
    }
 
    input {
      width: 100%;
      padding: 8px;
      margin-bottom: 16px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
    }
 
    button {
      background-color: #5e057e;
      color: #fff;
      padding: 10px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-weight: bold;
      transition: background-color 0.3s;
    }
 
    button:hover {
      background-color: #299d00;
    }
 
    .form-footer {
      text-align: center;
      margin-top: 20px;
      color: #888;
    }
 
    .error-message,
    .logout-message {
      background-color: #5e057e;
      color: #fff;
      padding: 10px;
      border-radius: 3px;
      text-align: center;
    }
  </style>
</head>
 
<body>
  <div class="container">
    <div class="form-container">
 
      <div th:if="${param.error}">
        <div class="error-message">
          <p>Invalid Username or Password</p>
        </div>
      </div>
 
      <div th:if="${param.logout}">
        <div class="logout-message">
          <p>Logout Successful!</p>
        </div>
      </div>
 
      <h2>Login</h2>
      <form th:action="@{/login}" method="post" role="form" th:object="${user}">
 
        <label for="username">Username:</label>
        <input th:field="*{username}" type="text" id="username" name="username" 
          placeholder="Enter your Username" required>
 
        <label for="password">Password:</label>
        <input th:field="*{password}" type="password" id="password" name="password" 
          placeholder="Enter your Password" required>
 
        <button type="submit">Login</button>
      </form>
      <p class="form-footer">Don't have an account? <a th:href="@{/register}">Register</a>here.</p>
    </div>
  </div>
</body>
 
</html>
Project Structure

Project Structure

MySQL Workbench as Database

MySQL Workbench as Database

Run the Application

  • To run this application right-click on the application, click Run As, and then select the Java Application option.
  • Open Chrome and Enter this URL in the search bar localhost:8080/register you will see the page like this.
Login page ./login

Login page ./login

Register page ./register

Register page ./register

Dashboard page ./home

Dashboard page ./home

Experiment 9
Objective: Test RESTful web services using Spring Boot.

Theroy:
A RESTful web service is a service that follows the principles of Representational State Transfer (REST) architecture. REST is an architectural style for designing networked applications. It relies on a stateless, clint-server, cacheable communications protocol the HTTP. RESTful applications use HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources, which are typically represented by JSON or XML.

create a spring boot application:

  • Use Spring Initializer https://start.spring.io to generate a new Spring Boot Project with dependencies:
  • Spring Web
  • Spring Data JPA
  • H2 Database (for an in-memory database)
Project Structure

Project Structure

Add all these code in your project:

src/main/java/net.springboot.spring/SpringBootRest2Application.java
package net.springboot.spring;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class SpringBootRest2Application {
 
  public static void main(String[] args) {
    SpringApplication.run(SpringBootRest2Application.class, args);
  }
}
src/main/java/net.springboot.spring.beans/student.java
package net.springboot.spring.beans;
 
public class Student {
  String name;
  int age;
  String registrationNumber;
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public int getAge() {
    return age;
  }
 
  public void setAge(int age) {
    this.age = age;
  }
 
  public String getRegistrationNumber() {
    return registrationNumber;
  }
 
  public void setRegistrationNumber(String registrationNumber) {
    this.registrationNumber = registrationNumber;
  }
}
src/main/java/net.springboot.spring.beans/StudentRegistration.java
package net.springboot.spring.beans;
 
import java.util.ArrayList;
import java.util.List;
 
public class StudentRegistration {
  private List<Student> studentRecords;
  private static StudentRegistration stdregd = null;
 
  private StudentRegistration() {
    studentRecords = new ArrayList<Student>();
  }
 
  public static StudentRegistration getInstance() {
    if (stdregd == null) {
      stdregd = new StudentRegistration();
      return stdregd;
    } else {
      return stdregd;
    }
  }
 
  public void add(Student std) {
    studentRecords.add(std);
  }
 
  public String upDateStudent(Student std) {
    for (int i = 0; i < studentRecords.size(); i++) {
      Student stdn = studentRecords.get(i);
      if (stdn.getRegistrationNumber().equals(std.getRegistrationNumber())) {
        studentRecords.set(i, std);// update the new record return "Update successful";
      }
    }
 
    return "Update un-successful";
  }
 
  public String deleteStudent(String registrationNumber) {
    for (int i = 0; i < studentRecords.size(); i++) {
      Student stdn = studentRecords.get(i);
      if (stdn.getRegistrationNumber().equals(registrationNumber)) {
        studentRecords.remove(i);// update the new record return "Delete successful";
      }
    }
    return "Delete un-successful";
  }
 
  public List<Student> getStudentRecords() {
    return studentRecords;
  }
}
src/main/java/netnet.springboot.spring.beans/StudentRegistrationReply.java
package net.springboot.spring.beans;
 
public class StudentRegistrationReply {
  String name;
  int age;
  String registrationNumber;
  String registrationStatus;
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public int getAge() {
    return age;
  }
 
  public void setAge(int age) {
    this.age = age;
  }
 
  public String getRegistrationNumber() {
    return registrationNumber;
  }
 
  public void setRegistrationNumber(String registrationNumber) {
    this.registrationNumber = registrationNumber;
  }
 
  public String getRegistrationStatus() {
    return registrationStatus;
  }
 
  public void setRegistrationStatus(String registrationStatus) {
    this.registrationStatus = registrationStatus;
  }
}
src/main/java/net.springboot.spring.controllers/StudentRetriveController.java
package net.springboot.spring.controllers;
 
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import net.springboot.spring.beans.Student;
import net.springboot.spring.beans.StudentRegistration;
 
@Controller
public class StudentRetrieveController {
  @RequestMapping(method = RequestMethod.GET, value = "/student/allstudent")
  @ResponseBody
  public List<Student> getAllStudents() {
    return StudentRegistration.getInstance().getStudentRecords();
  }
}
src/main/java/net.springboot.spring.controllers/StudentRegistrationController.java
package net.springboot.spring.controllers;
 
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import net.springboot.spring.beans.*;
 
@Controller
public class StudentRegistrationController {
  @RequestMapping(method = RequestMethod.POST, value = "/register/student")
  @ResponseBody
  public StudentRegistrationReply registerStudent(@RequestBody Student student) {
    System.out.println("In registerStudent");
    StudentRegistrationReply stdregreply = new StudentRegistrationReply();
    StudentRegistration.getInstance().add(student);
    // We are setting the below value just to reply a message back to the caller
    // stdregreply.setName(student.getName()); stdregreply.setAge(student.getAge());
    // stdregreply.setRegistrationNumber(student.getRegistrationNumber());
    // stdregreply.setRegistrationStatus("Successful");
 
    return stdregreply;
  }
}
pom.xml
<?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.bhaiti.kela</groupId>
  <artifactId>spring-boot-rest-2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>spring-boot-rest-2</name>
  <description>Demo project for Spring Boot</description>
 
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.BUILD-SNAPSHOT</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
 
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
 
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
 
  <repositories>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
 
  <pluginRepositories>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
 
      </snapshots>
    </pluginRepository>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
  </pluginRepositories>
 
</project>
src/main/resources/application.properties
server.port=8083 
spring.profiles.active=@spring.profiles.active@
src/main/java/net.springboot.spring.controllers/StudentUpdateController.java
package net.springboot.spring.controllers;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import net.springboot.spring.beans.Student;
import net.springboot.spring.beans.StudentRegistration;
 
@Controller
public class StudentUpdateController {
 
  @RequestMapping(method = RequestMethod.PUT, value = "/update/student")
 
  @ResponseBody
  public String updateStudentRecord(@RequestBody Student stdn) {
    System.out.println("In updateStudentRecord");
    return StudentRegistration.getInstance().upDateStudent(stdn);
  }
}
src/main/java/net.springboot.spring.controllers/StudentDeleteController.java
package net.springboot.spring.controllers;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.PathVariable;
 
import net.springboot.spring.beans.StudentRegistration;
 
@Controller
public class StudentDeleteController {
  @RequestMapping(method = RequestMethod.DELETE, value = "/delete/student/{regdNum}")
  @ResponseBody
  public String deleteStudentRecord(@PathVariable("regdNum") String regdNum) {
    System.out.println("In deleteStudentRecord");
    return StudentRegistration.getInstance().deleteStudent(regdNum);
  }
}
Experiment 10
Objective: Test Frontend web application with Spring Boot.

Theory:
Testing a frontend web application involves ensuring that the user interface works as expected, including user interactions, data displays, and integration with backend services. testing can be broadly categorized into the following types:

  • Unit Testing: Tests individual components or functions in isolation.
  • INtegration Testing: Tests intractions between multiple components or services.
  • End-to-End (E2E) Testing: Tests the entire application flow from start to finish, as a user would interact with it.

create a spring boot application:

  • Use Spring Initializer https://start.spring.io to generate a new Spring Boot Project with dependencies:
  • Spring Web
  • Spring Boot MVC
  • Thymeleaf
  • Spring Data JPA
  • H2 Database (for an in-memory database)
  • JUnit/ Mockito / Selenium.
Project Structure

Project Structure

Add all these code

pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
src/main/java/net.sourcecode.spring.domain/User.java
package net.sourcecode.spring.domain;
import jakarta.persistence.*;
 
@Entity
@Table(name = "users")
public class User {
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
 
    @Column(name = "name")
    private String name;
 
    public User() {
    }
 
    public User(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}
src/main/resources/application.properties
spring.application.name=spring
logging.level.org.springframework=INFO
 
################### Hibernate Configuration ##########################
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
src/main/resources/data.sql
delete from users;
 
insert into users(id, name) values(1,'Admin');
insert into users(id, name) values(2,'Ram');
insert into users(id, name) values(3,'Krishna');
src/main/java/net.sourcecode.spring.repositories/UserRepository.java
package net.sourcecode.spring.repositories;
 
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.domain.User;
 
public interface UserRepository extends JpaRepository<User, Integer> {
}
src/main/java/net.sourcecode.spring.web.controllers/HomeController.java
package net.sourcecode.spring.web.controller;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import net.sourcecode.spring.repositories.UserRepository;
 
@Controller
public class HomeController {
 
    @Autowired
    UserRepository userRepository;
 
    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("users", userRepository.findAll());
        return "index";
    }
}
 
src/main/resources/templates/index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    <title>Spring Boot Web App using Spring MVC and Spring Data JPA</title>
</head>
<body>
    <h1>Spring Boot Web App using Spring MVC and Spring Data JPA</h1>
    <hr />
    <table>
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="user : ${users}">
                <td th:text="${user.id}">Id</td>
                <td th:text="${user.name}">Name</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
src/main/java/net.sourcecode.spring/Application.java
package net.sourcecode.spring;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}