Oops Java Lab Object Oriented Programming with Java lab
Last updated: June 25, 2024
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.
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:
sudo apt-get install default-jdk
java -version
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.
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.
29 is a prime no.
Here's a simple Java program that calculates the factorial of a given number.
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 .
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
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:
javac Calculator.java
Once compiled successfully, run the program with command-line arguments as:
java Calculator 5 + 3
Result: 8.0
Similarly, we can perform other operations like subtraction, multiplication and division:
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.
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 ();
}
}
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 )
// 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 ();
}
}
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.
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 ));
}
}
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.
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 ();
}
}
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.
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" );
}
}
Exception caught in catch block
finally block executed
Outside try-catch-finally clause
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.
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." );
}
}
}
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.
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 ());
}
}
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.
package M y P ack;
// 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.
javac -d . PackageDemo.java
package M y P ack;
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.
javac -d . PackageImportDemo.java
For run this code we need to type package name
with .class
file name.
java MyPack.PackageImportDemo
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.
First we need to create the .txt
file with the name input. Write something in input.txt
file.
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.
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
.
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 .
success...
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.
Welcome to javaTpoint.
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
Create the file and packages add these code
<? 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 >
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
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 + "]" ;
}
}
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 );
}
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 + "]" ;
}
}
import com.Springboot.UserAuth.Entity.User;
import com.Springboot.UserAuth.dto.UserDto;
public interface UserService {
User findByUsername (String username );
User save (UserDto userDto );
}
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);
}
}
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 ;
}
}
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" ));
}
}
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 ());
}
}
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" ;
}
}
<! 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 : 40 px ;
text-align : center ;
}
.dashboard_title {
font-size : 24 px ;
margin-top : 0 ;
}
.dashboard_user {
margin-top : 20 px ;
}
.dashboard_user_name {
font-size : 18 px ;
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 >
<! 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 : 100 vh ;
background-color : #f4f4f4 ;
}
.form-container {
background-color : #fff ;
width : 400 px ;
padding : 20 px ;
border-radius : 8 px ;
box-shadow : 0 0 10 px rgba ( 0 , 0 , 0 , 0.1 );
}
h2 {
color : #5e057e ;
text-align : center ;
margin-bottom : 20 px ;
}
label {
display : block ;
margin-bottom : 8 px ;
color : #5e057e ;
}
input {
width : 100 % ;
padding : 8 px ;
margin-bottom : 16 px ;
border : 1 px solid #ccc ;
border-radius : 4 px ;
box-sizing : border-box ;
}
button {
background-color : #5e057e ;
color : #fff ;
padding : 10 px 20 px ;
border : none ;
border-radius : 4 px ;
cursor : pointer ;
font-weight : bold ;
transition : background-color 0.3 s ;
}
button :hover {
background-color : #299d00 ;
}
.form-footer {
text-align : center ;
margin-top : 20 px ;
color : #888 ;
}
.success-message {
background-color : #5e057e ;
color : #fff ;
padding : 10 px ;
border-radius : 3 px ;
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 >
<! 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 : 100 vh ;
background-color : #f4f4f4 ;
}
.form-container {
background-color : #fff ;
width : 400 px ;
padding : 20 px ;
border-radius : 8 px ;
box-shadow : 0 0 10 px rgba ( 0 , 0 , 0 , 0.1 );
}
h2 {
color : #5e057e ;
text-align : center ;
margin-bottom : 20 px ;
}
label {
display : block ;
margin-bottom : 8 px ;
color : #5e057e ;
}
input {
width : 100 % ;
padding : 8 px ;
margin-bottom : 16 px ;
border : 1 px solid #ccc ;
border-radius : 4 px ;
box-sizing : border-box ;
}
button {
background-color : #5e057e ;
color : #fff ;
padding : 10 px 20 px ;
border : none ;
border-radius : 4 px ;
cursor : pointer ;
font-weight : bold ;
transition : background-color 0.3 s ;
}
button :hover {
background-color : #299d00 ;
}
.form-footer {
text-align : center ;
margin-top : 20 px ;
color : #888 ;
}
.error-message ,
.logout-message {
background-color : #5e057e ;
color : #fff ;
padding : 10 px ;
border-radius : 3 px ;
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
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
Register page ./register
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
Add all these code in your project:
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);
}
}
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;
}
}
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;
}
}
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;
}
}
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 ();
}
}
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;
}
}
<? 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 >
server.port =8083
spring.profiles.active =@spring.profiles.active@
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);
}
}
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
Add all these code
< 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 >
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;
}
}
spring.application.name =spring
logging.level.org.springframework =INFO
################### Hibernate Configuration ##########################
spring.jpa.hibernate.ddl-auto =update
spring.jpa.show-sql =true
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' );
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 > {
}
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" ;
}
}
<! 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 >
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);
}
}