BACK 
										
									

Springboot Tutorial

Springboot Pre-Requisites: Knowledge on Core Java, JDBC, Servlets, MVC Architecture For Application level understanding need Spring, Spring MVC Database - MySQL Knowledge Springboot Springboot Introduction: · Spring Boot is an open-source. · Spring Boot is a java-based framework. · Helps in bootstrapping the Spring Application. · Makes easy for creating stand-alone applications. · Makes easy of production-grade Spring based Applications. · Spring Boot simplifies the process of creating a Spring based Application. · Need not worry about making jar/war and deploying it into any web server. · Spring Boot internally does tasks and configurations. · Embedded web servers. · Spring module provides RAD (Rapid Application Development) feature for Spring framework. · SpringBoot = Spring Framework + Embedded HTTP servers – XML (Bean Configuration or @Configuration) Core Principles: · Autoconfiguration · Opinionated · Configuration convention · Reduced boilerplate code Autoconfiguration · Automatically configures the application based on the provided dependencies. · Developers need not to configure the application. · Spring Boot will configure the application based on the provided default settings for applications. Opinionated · Spring Boot is an opinionated framework. · Spring Boot provides opinions for configuring and running the application. · Simplifies the development process. Convention over Configuration · Spring Boot provides acceptable default settings for configuration. · Developers only need to provide configuration when they want to override the defaults. Eliminates Boilerplate Code · Spring Boot reduces the amount of boilerplate code. · Developers can focus on writing business logic instead of writing boilerplate code. · For example, using JDBC, we need to write a lengthy code just to get a connection with the database. · Instead, we need to provide values of database properties in 3-4 lines through the properties file to get a database connection. Spring Boot points: · Application can be developed in very short duration. · Developing a production-ready application. Spring Boot: 1. Speed-up the project development. 2. Easier and faster way to configure, set up & run both web-based as well as simple applications. 3. No web-servers such as (Tomcat, Jetty, Undertow) are required to configure separately. 4. Reduced XML configurations and promotes annotations. 5. Combines more than one annotation of Spring framework & replaces them by introducing a single annotation. Example: three annotations combination: @SpringBootApplication = @EnableAutoConfiguration + @Configuration + @ComponentScan 6. Reduced developer efforts for delivering enterprise-level application. 7. Provides ready-made functionalities (common and applicable to any project which eliminates boiler plate code). 8. Creates stand-alone application that can be run using jar file. 9. Configures Spring and third-party libraries automatically. 10. Provides production-ready features (health checks, metrics, and externalized configurations). 11. Provides third party tools integration easy. 12. Great support for developing Microservices. 13. Integrates easy with Spring JDBC, Spring ORM, Spring Data, Spring Security, Spring Web MVC etc. 14. Databases integration becomes easy. 15. Develops ready-made starter projects too quickly. 16. Provides command line interface (CLI) to develop and test applications quickly. 17. Spring Boot 3.0 is officially released in November, 2022. 18. Spring Boot released 3.0 after the release of Spring Boot 2.0. 19. Spring Boot GA release supports Spring Framework 6.0. 20. Spring 3.0 Release incorporate: A Java 17 baseline. 21. Spring 3.0 Support for Jakarta EE 10 with an EE 9 baseline. 22. Spring 3.0 Support for generating native images with GraalVM. 23. Spring 3.0 Improves observability with Micrometer and Micrometer Tracing. Create a Spring Boot Application ways: 1) Using Spring Boot CLI Tool 2) Using Spring STS IDE 3) Using Spring Initializr Website Spring Boot advantages: 1) Spring Boot Starters 2) Reducing Boilerplate Code 3) Embedded Servers 4) Easier to connect with Databases 5) Supports development of Microservices 6) Default setup for Testing 7) Run Application as a jar file 8) Spring Boot Profile to easy switch environment 9) Spring Boot Actuator for Application Monitoring 10) Increases Productivity and minimizes Development time Starters in Spring Boot: · Starters are the readymade small projects that we can include in application. · Also called dependency descriptors. · Starters contains dependencies that required to get a project up and running quickly. (supports with a consistent, supported set of managed transitive dependencies). · To start with Spring Web Application, include the spring-boot-starter-web dependency. · The STS will automatically add the ‘spring-boot-starter-web’ dependency in pom.xml. Starters: org.springframework.boot group: spring-boot-starter · Core starter, including auto-configuration support, logging and YAML spring-boot-starter-activemq · Starter for JMS messaging using Apache ActiveMQ spring-boot-starter-aop · Starter for aspect-oriented programming with Spring AOP and AspectJ spring-boot-starter-data-jpa · for using Spring Data JPA with Hibernate spring-boot-starter-batch · for using Spring Batch spring-boot-starter-cache · Starter for using Spring Framework’s caching support spring-boot-starter-data-jdbc · Starter for using Spring Data JDBC spring-boot-starter-data-ldap · for using Spring Data LDAP spring-boot-starter-data-mongodb · for using MongoDB document-oriented database and Spring Data MongoDB spring-boot-starter-validation · Starter for using Java Bean Validation with Hibernate Validator spring-boot-starter-data-elasticsearch · Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch spring-boot-starter-data-rest · for exposing Spring Data repositories over REST using Spring Data REST spring-boot-starter-freemarker · for building MVC web applications using FreeMarker views spring-boot-starter-integration · Starter for using Spring Integration spring-boot-starter-jersey · Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to starter-web spring-boot-starter-json · for reading and writing json spring-boot-starter-mail · for using Java Mail and Spring Framework’s email sending support spring-boot-starter-security · Starter for using Spring Security spring-boot-starter-test Starter · for testing SpringBoot applications with libraries including JUnit Jupiter, Hamcrest and Mockito spring-boot-starter-web · for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container spring-boot-starter-webflux · for building WebFlux applications using Spring Framework’s Reactive Web support. spring-boot-starter-thymeleaf · Starter for building MVC web applications using Thymeleaf views. Starters to get Production Ready: · Actuator module provides all production-ready features. · To enable the features, add a dependency on the spring-boot-starter-actuator ‘Starter’. spring-boot-starter-actuator · Starter for using Actuator which provides production ready features to help you monitor and manage your application. Spring Boot 3.0: · Released in November, 2022. (new features and improvements). · Major release after release of Spring Boot 2.0. · First Spring Boot GA release to support Spring Framework 6.0. · New release was the dropping of support for older versions of Java. Major highlights of the Spring 3.0 Release: · A Java 17 baseline · Supports of Jakarta EE 10 with an EE 9 baseline · Supports to generate native images with GraalVM, superseding the experimental Spring Native project. · Micrometer and Micrometer Tracing observability improved. Use the Spring Boot 3: · Spring Boot 3.0 is the neglecting support for older versions of Java. · Require minimum Java 17 in order to work with Spring Boot 3.0. · Became mandatory to have JDK 17 environment before going to Spring Boot 3.0. New features in Spring Boot 3 and Spring 6: · Spring Boot 3.0 builds on and requires Spring Framework 6. · POM.xml points to Spring Boot version 3.0.0. · POM.xml automatically download the required dependencies of Spring framework 6 (By default). Java 17 Base line and Java 19 Support · Java 17 as a minimum version to work with Spring 3.0. · If you are currently using lower versions such as Java 8, Java 11 or Java 14, upgrade JDK to JDK 17 before starting development of applications using Spring Boot 3.0. · Latest version of Java is JDK 20. · Spring Boot 3.0 also works well with JDK 19. Third-party Library Upgrades · Java EE has been changed to Jakarta EE. · Spring Boot 3.0 has also migrated from Java EE to Jakarta EE APIs for all dependencies. · package names starting with 'javax' need to be changed to 'jakarta'. Commonly used packages will be changed: javax.persistence.* -> jakarta.persistence.*; javax.validation.* -> jakarta.validation.*; javax.servlet.* -> jakarta.servlet.*; javax.annotation.* -> jakarta.annotation.*; javax.transaction.* -> jakarta.transaction.*; Note: package javax.sql.* will not change to ‘jakarta.*’ as they are part of Java 17 JDK, not of Java EE. Note: Only those packages which are part of Java EE will change to Jakarta EE. Jakarta EE 10 compatible dependencies have been chosen, including: · Jakarta Activation 2.1 · Jakarta JMS 3.1 · Jakarta JSON 2.1 · Jakarta JSON Bind 3.0 · Jakarta Mail 2.1 · Jakarta Persistence 3.1 · Jakarta Servlet 6.0 · Jakarta Servlet JSP JSTL 3.0 · Jakarta Transaction 2.0 · Jakarta Validation 3.0 · Jakarta WebSocket 2.1 · Jakarta WS RS 3.1 · Jakarta XML SOAP 3.0 · Jakarta XML WS 4.0 Note: Spring Framework is upgraded to version 6. Other Spring Projects also upgraded in this release are: · Spring AMQP 3.0. · Spring Batch 5.0. · Spring Data 2022.0. · Spring GraphQL 1.1. · Spring HATEOAS 2.0. · Spring Integration 6.0. · Spring Kafka 3.0. · Spring LDAP 3.0. · Spring REST Docs 3.0. · Spring Retry 2.0. · Spring Security 6.0 (see also what’s new). · Spring Session 3.0 · Spring WS 4.0. Migrating Spring Boot 2 To Spring Boot 3 Step#1: Install JDK 17 in your System · JDK versions lower than JDK 17, the Spring Boot 3.0 will no longer support it and migration will not be successful. · Mandatory to get JDK 17 installed. · Spring Boot 3.0 requires JDK 17 as a minimum JDK to work with it. Step#2: Upgrade your project to latest available Spring Boot 2.7.x version · Upgrade to the latest available 2.7.x version. · Migration strategy to upgrade step by step. · Otherwise, you may require to change a lot of configurations. · Because of multiple new features and API changes and it may also make the migration too complex. · Approach to Make sure that we are building against the most recent dependencies. Step#3: Review Existing Dependencies · Spring Boot 3.0 has upgraded a multiple number of dependencies (review of dependencies is important). · Spring Boot migration guidelines provide the list of dependencies for both 2.7.x and 3.0.x versions. · In order to access how your project can be affected due to dependencies, you can · Review dependency management for 2.7.x with dependency management for 3.0.x in order to access how affected in project. Review Specific to Spring Security Dependency · Spring Boot 3.0 uses Spring Security 6.0. · Spring Security released Spring Security 5.8 to simplify upgrading to Spring Security 6.0. · Recommended to upgrade Spring Boot 2.7 application to Spring Security 5.8. · Spring Security has prepared a Spring Boot Security migration guide that to help to do so. Step#4: Review Deprecations from Spring Boot 2.x · Some of the classes, methods, properties and annotations that were deprecated in Spring Boot 2.x have been removed. · Example: WebSecurityConfigurerAdapter class, @EnableGlobalWebSecurity. · Changes: Methods authorizeRequests() and antMatchers() are also changed to authorizeHttpRequests() and requestMatchers(). Step#5: Upgrade to Spring Boot 3 · Open POM.xml and update the version of Spring Boot as: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> • Once updated, save the pom.xml and maven dependencies will be downloaded. Step#6: Fix Compilation Errors and Deprecated elements · Once upgrade to Spring Boot 3.0.0 finishes, actual effect of artifacts will be shown. · Fix compilation errors and deprecated elements based on the data (if any). Step#7: Configuration Properties Migration · A few configuration properties were also renamed/removed in Spring Boot 3.0. · Required to update ‘application.properties’. · Spring Boot provides a ‘spring-boot-properties-migrator’ module in order to help us in migrating it. · Add the ‘spring-boot-properties-migrator’ by adding the dependency to ‘pom.xml’: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope> </dependency> Note: Once you have completed migration, please remove this dependency from the ‘pom.xml’. Step#8: Update packages starting from ‘javax’ to ‘jakarta’ · Java EE has been changed to Jakarta EE, Spring Boot 3.0. · Upgraded from Java EE to Jakarta EE APIs for all dependencies. · Jakarta EE 10 compatible dependencies have been opted. · Package names starting with ‘javax’ need to be changed to ‘jakarta’. Step#9: Verify upgrades on Core Changes (if any) · Changes made to the core of Spring Boot will be appropriate to most applications. Step#10: Review Upgrades on Web Applications · Upgrading a web application - verify: Note: Spring MVC and WebFlux URL Matching Changes @RestController public class EmployeeController { @GetMapping("/emp/register") public String showRegisterPage { return "register"; } } · Spring Framework 6.0, the trailing slash matching configuration option has been deprecated. · Previous controller would match both “/emp/register” and “/emp/register/”. · After Spring Framework upgrade, now onwards “/emp/register/” doesn’t match with “/emp/register” by default and will result in an HTTP 404 error. · Hence, don’t insert trailing slash while matching the URLs. Spring: · Spring Framework is a popular application development framework of Java. · Spring Framework important feature is dependency Injection or Inversion of Control (IoC). · Spring Framework will help to develop a loosely coupled application. · Massive Framework involves lots of steps for setup process related to configuration. · These steps involve dependency management. · As the project scope increases, it is difficult to manage dependency management. Spring Boot: · Spring Boot is a module of Spring Framework. · For building a stand-alone application without or minimum configuration settings. · Use Springboot for developing Spring-based application or RESTful services. · Springboot can be started with minimum Spring configuration setup instead of entire setup configurations. · Easily can be understand and developed. · Productivity is increased and time of development is reduced. · Spring XML configuration complexities are reduced. · For Springboot, MAVEN dependency management tool is used. · Archetype is MAVEN project template tool which is defined as model from and with which all other necessary things will be made. Spring MVC: · To build web applications, use Spring MVC which is Web MVC Framework. · It consists of configuration files for various abilities. · Spring MVC is HTTP oriented web application development framework. · It specifies each dependency separately. · More time taking than Spring boot. Spring vs Spring Boot: 1. Configuration Spring: · Needs setting up configuration such as XML, annotation, or Java-based configurations. · Manual configurations needed. Spring Boot: · Default setup process, specifying beans setup is reduced. · XML configuration is not needed and not to be configured. 2. Bootstrapping a Project Spring: · Time-consuming in project setup process. · All dependencies should be included before usage. · Spring Boot: · Spring Initializr is used for rapid project bootstrapping. · Implicitly dependencies configured using its starter templates. 3. Embedded Server Spring: · No embedded server. · Need to set up an external server and application needs to deploy in external server. · Spring Boot: · In-built Embedded Tomcat allows to run application independently. 4. Production-Ready Features Spring: · Additional setup needed for features such as health checks and metric collection. Spring Boot: · Built-in tools such as Spring Boot Actuator to monitor and manage production applications. 5. Properties & Configuration Spring: · hierarchy and property source setup must be configured explicitly. Spring Boot: · Provides defaults and environment-specific configurations. 6. Deployment Spring: · Generates WAR files deployed to external application servers. Spring Boot: · Generates standalone JAR with embedded servers for deployment. 7. Testing Spring: · Requires extra configuration and setup for mocking and integration testing. Spring Boot: · Provides built-in test configuration. · Mocking with @MockBean and @SpringBootTest is simplified. 8. Microservices Spring: · Due to the necessary manual configurations is tough to work with microservices. Spring Boot: · Integrated with Spring Cloud, easy to build and scale microservices. Spring Boot Architecture: Layers of Spring boot: · Presentation Layer o Views of the application or front-end part. · Business Layer o Which consists of business logic, service, services provided by data access. · Persistence Layer o storage logic and converts business objects database records. · Database Layer o Different operations pertaining to DB. Functional Architecture: Methods and Status Codes: HTTP Status Codes server returns a status code on every HTTP request. These indicates the request processing status. 1xx Informational To indicate informational content. Indicates that the request is received and processing. informational status codes: 100 Continue: indicates that the server has received the request header and the client can now send the body content. First, client makes a request (with the Expect: 100-continue header) to check whether it can start with a partial request. The server can then respond either with 100 Continue (OK) or 417 Expectation Failed (No) along with an appropriate reason. 101 Switching Protocols: indicates that the server is OK for a protocol switch request from the client. 102 Processing: for long-running processing to prevent the client from timing out. Indicates client to wait for the future response, which will have the actual response body. 2xx Success indicates the successful processing of requests. 200 OK: indicates that the request is successful, and the response content is returned to the client. 201 Created: indicates that the request is successful,and a new resource is created. 204 No Content: indicates that the request is processed successfully, but there's no return value for this request. Example: when response to the deletion of a resource. 3xx Redirection indicates that the client needs to perform further actions to logically end the request. 304 Not Modified: indicates that the resource has not been modified since it was last accessed. This is returned only when allowed by the client via setting the request headers as If-Modified-Since or If-None-Match. The client can take appropriate action based on this status code. 4xx Client Error indicates an error in processing the request. 400 Bad Request: indicates that the server failed to process the request. improper syntax in the request. client can correct the request and try to request again. 401 Unauthorized: indicates that authentication is required for the resource. client can try again with appropriate authentication. 403 Forbidden: indicates that the server is refusing to respond to the request even if the request is valid. reason is listed in the body content if the request is not a HEAD method. 404 Not Found: indicates that the requested resource is not found at the location specified in the request. 405 Method Not Allowed: indicates that the HTTP method specified in the request is not allowed on the resource identified by the URI. 408 Request Timeout: indicates that the client failed to respond within the time window set on the server. 409 Conflict: This code indicates that the request cannot be completed because it conflicts with some rules established on resources, such as validation failure. 5xx Server Error indicates server failures while processing a valid request. 500 Internal Server Error: indicates a generic error message, and it tells that an unexpected error occurred on the server and that the request cannot be fulfilled. 501 (Not Implemented): The server either does not recognize the request method, or it cannot fulfill the request. future availability Example: new feature of a web-service API. Summary of HTTP Status Codes 1×× Informational 100 Continue 101 Switching Protocols 102 Processing 2×× Success 200 OK 201 Created 202 Accepted 203 Non-authoritative Information 204 No Content 205 Reset Content 206 Partial Content 207 Multi-Status 208 Already Reported 226 IM Used 3×× Redirection 300 Multiple Choices 301 Moved Permanently 302 Found 303 See Other 304 Not Modified 305 Use Proxy 307 Temporary Redirect 308 Permanent Redirect 4×× Client Error 400 Bad Request 401 Unauthorized 402 Payment Required 403 Forbidden 404 Not Found 405 Method Not Allowed 406 Not Acceptable 407 Proxy Authentication Required 408 Request Timeout 409 Conflict 410 Gone 411 Length Required 412 Precondition Failed 413 Payload Too Large 414 Request-URI Too Long 415 Unsupported Media Type 416 Requested Range Not Satisfiable 417 Expectation Failed 418 I’m a teapot 421 Misdirected Request 422 Unprocessable Entity 423 Locked 424 Failed Dependency 426 Upgrade Required 428 Precondition Required 429 Too Many Requests 431 Request Header Fields Too Large 444 Connection Closed Without Response 451 Unavailable For Legal Reasons 499 Client Closed Request 5×× Server Error 500 Internal Server Error 501 Not Implemented 502 Bad Gateway 503 Service Unavailable 504 Gateway Timeout 505 HTTP Version Not Supported 506 Variant Also Negotiates 507 Insufficient Storage 508 Loop Detected 510 Not Extended 511 Network Authentication Required 599 Network Connect Timeout Error Spring boot web application: Steps for Creating a Spring Boot Project: 1. Create the database. 2. Creating an application. 3. Setting application.properties file. 4. Creating an entity class. 5. Create REST Controller class with cross origin. 6. Create a service interface which has abstract methods. 7. Create an implementation class which implements the service interface. 8. Create an JPA Repository Step 1: Create the database. Syntax: create database database_name; Example: create database mydb; Step 2: Creating the application · Go to https://start.spring.io/ · Select Language as JAVA · Select the Project as MAVEN (Build Tool) · Select Spring Boot 3.2.1 · Provide the Metadata such as Group, Artifact, Name of the Project, Description of the project, package name. · Group ID in Maven: An XML element in the POM.xml file of a Maven project the specifies the id of the project group. · Group ID helps to identify the project group. · Artifact ID in Maven: An XML element in the POM.xml of a maven project that specifies the id of the project (artifact). · Artifact ID helps to identify the project. · Select packaging as JAR · Select the Java JDK version as 17 · Add the dependencies by clicking on "ADD DEPENDENCIES" button. · Add the following dependencies o Spring Web o Spring Boot DevTools o Spring Data JPA o MySQL Driver · Click on Generate · Project rar/ zip file will be downloaded. · Extract the project to a specific folder. · Go to eclipse/ STS. · Click on File -> Import. · Click on Existing Maven Projects · Select the project which was downloaded and extracted. · Click on Finish · Maven project will be added to the eclipse and will be built as per the dependencies selected. · Below is the project structure. POM.xml file dependencies: <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-web</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> </dependencies> Note: Spring Web dependency: · Build web, including RESTful, applications using Spring MVC. Uses Apache Tomcat as the default embedded container. Spring Boot DevTools dependency: · Provides fast application restarts, LiveReload, and configurations for enhanced development experience. Spring Data JPA SQL dependency: · Persist data in SQL stores with Java Persistence API using Spring Data and Hibernate. MySQL Driver SQL dependency: · MySQL JDBC driver. spring-boot-starter-parent · provides all maven defaults required for any spring project. · For developing a web application, we also need spring-boot-starter-web dependency to add which include additional dependencies such as Spring boot, tomcat etc., which are needed for our application. Note: · When we are creating Spring MVC Hibernate MySQL project, it may be confused with a lot of dependencies it requires and its versions also. · We need to configure DataSource, EntitymanagerFactory, TransactionManager etc beans. · Spring cannot do it implicitly for us. · Spring Boot will take care of implicit configuration for us. SpringbootExampleApplication class & @SpringBootApplication package com.example.SpringbootExample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootExampleApplication { public static void main(String[] args) { SpringApplication.run(SpringbootExampleApplication.class, args); } } Note: @SpringBootApplication · Indicates a configuration class that declares one or more @Bean methods and triggers auto-configuration and component scanning. · This is equivalent to declaring @SpringBootConfiguration, @EnableAutoConfiguration and @ComponentScan. Step 3: Setting application.properties file. Set the application.properties file: spring.datasource.url = jdbc:mysql://localhost:3306/mydb spring.datasource.password=root spring.datasource.username=root # Hibernate ddl auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect # The dialect specifies the type of database used in hibernate so that hibernate generate appropriate type of SQL statements. # For connecting any hibernate application with the database, it is required to provide the configuration of SQL dialect. Note: If you are using Oracle database, example for Oracle10g dialect: Dialorg.hibernate.dialect.Oracle10gDialect org.hibernate.dialect.OracleDialect (works with Oracle any version) Note: @GetMapping for HomeController import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HomeController { @GetMapping("/") public String getMessage() { return"---------Hello Vishwanath Arabati Spring Boot App GET Method ------------"; } Note: @PostMapping for HomeController import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @PostMapping("/") public String postMessage() { return"---------Hello Vishwanath Arabati Spring Boot App POST Method ------------"; } Step 4: Creating entity Class: · In the above project structure, com.example.SrpringbootExample package consists of SpringboootExampleApplication.java file (which consist of main method). · Right click on src – new – create a new class in package (this package MUST be under the package com.example.SpringbootExample) · Create a package with the name com.example.SpringbootExample.model in the folder src/main/java. · Create a class under the above package. · Create a model class with the name Student. Student class Model consists of: o Define four variable studentID, studentFirstName, studentLastName. o Generate Getters and Setters for all the attributes. o CTRL + 3 and click on Generate Getters and Setters. o Mark/ Make the Student class as an Entity by using the annotation @Entity. o Mark the class as Table name by using the annotation @Table. o Define each variable as Column by using the annotation @Column. o Override the toString() method Student Model class: //mark class as an Entity @Entity //defining class name as Table name @Table public class Student{ …… } Note: To avoid the error: Table cannot be resolved to a type import: import jakarta.persistence.Entity; import jakarta.persistence.Table; Student class with attributes: @Entity @Table(name = "student") public class Student { private int studentID; private String studentFirstName; private String studentLastName; } Points: @Entity: Belongs to Java Persistence API (JPA). Indicates that class is a JPA entity which is mapped to a database table. @Table(name="users"): Belongs to JPA. Indicates the name of the database table that the mapped entity. @Id: Belongs to JPA. Indicates that the field id is the primary key. @GeneratedValue (strategy = GenerationType.IDENTITY): Belongs to JPA. Indicates that the primary key values are implicitly generated by the database using an identity column. @Column(nullable=false): Belongs to JPA. Indicates that the fields cannot be null in the table. @Column(nullable=false, unique=true): Belongs to JPA. Indicates that the field must be unique in the database table. @ManyToOne: Used to map the relationship of one entity with another entity. Example: We can have multiple student entities under a particular course. @JoinColumn: Foreign key reference to the one entity id for another entity. Example: This column to join the student entity with the Course entity class. @GeneratedValue annotation: · Used in conjunction with @Id annotation. · For implicitly generating unique values for primary key columns. · For specifying a primary key for that entity. · For marking the field property as a primary key of the entity, use @Id annotation. · Apply @GeneratedValue annotation to primary key field or property. · Hibernate implicitly generate a unique value for primary key field while persisting the entity. · @GeneratedValue annotation provides strategies for the generation of primary keys: o GenerationType.IDENTITY: § For generating the primary key value using the auto-increment column option. § It generates unique values. § Represents persistence provider must assign primary keys for the entity using a database identity column. o GenerationType.AUTO: § (Default strategy). § Implicitly selects generation strategy based on the database usage. § Represents that the persistence provider should pick an appropriate strategy for the specific database. o GenerationType.TABLE: § Uses a separate database table to generate primary key values. § This table is used for managing the persistence and uses it to allocate unique values for primary keys. § Represents that the persistence provider must assign primary keys for the entity using an underlying database table to ensure uniqueness. o GenerationType.SEQUENCE: § Uses a database sequence to generate primary key values. § Uses database sequence objects and depends on the database used. § Represents that the persistence provider must assign primary keys for the entity class using a database sequence. Constructors of Student Model: //default constructor public Student() {} //parameterized constructor public Student(int id, String fname, String lname) { this.studentID = id; this.studentFirstName = fname; this.studentLastName = lname; } Generate Getters and Setters: public int getStudentID() { return studentID; } public void setStudentID(int studentID) { this.studentID = studentID; } public String getStudentFirstName() { return studentFirstName; } public void setStudentFirstName(String studentFirstName) { this.studentFirstName = studentFirstName; } public String getStudentLastName() { return studentLastName; } public void setStudentLastName(String studentLastName) { this.studentLastName = studentLastName; } Add: @Id and @GeneratedValue @Id @GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY ) public int getStudentID() { return studentID; } Add: @Column @Column(name = "first_name", nullable = false) public String getStudentFirstName() { return studentFirstName; } Add: @Column @Column(name = "last_name", nullable = false) public String getStudentLastName() { return studentLastName; } @Override method: · To represent any object as a string. · Returns the String. · If we print object directly, toString() on the object will be called by compiler. · By toString() method overriding which returns the output in as per our written format (our own implementation). @Override public String toString() { //Coverted object as a string - override the toString() of the Object class return "Student [id=" + id + ", firstName=" + firstName +" + ", lastName=" + lastName +"]"; } Step 5: Create REST Controller class: · Create controller class StudentController in the package: package com.example.SpringbootExample.controller; · Decorate the StudentController class with @RestController annotation and @RequestMapping @RestController @RequestMapping("/student/api") public class StudentController { } · @RestController is useful for creating REST API Spring Application. · This RestController gives us JSON (JavaScript Object Notation) as response output. · Class with "@RestController" is treated as RestController. · Developing the REST API application in Spring Boot is taking less time to ready production-level applications. · Spring 4.0 introduced the @RestController. · It is a special @Controller annotation. · In @Restcontroller, need not to use @ResponseBody in the handler method. · @RestController view cannot be returned as output. · A class with @Controller is treated as a Controller class in Spring MVC. · @Controller is introduced in Spring 2.5. · @Controller is used for web application. · @Controller return as a view in Spring MVC. · In @Controller, need to use @ReponseBody in every handler method for response output without the view. · @RestController is the combination of @Controller and @ResponseBody for creating REST APIs. · @SpringBootApplication is enables @Configuration,@EnableAutoConfiguration and @ComponentScan annotations. · @Configuration can register extra beans with @Bean or import other configuration classes. · @EnableAutoConfiguration informs Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. · Example: if Spring Web MVC is on the classpath, @EnableAutoConfiguration annotation flags the application as a web application and activates setting up a DispatcherServlet. · @ComponentScan allows component scanning of the current package and also recursively scans sub-packages. Note: Import the packages to work with @RestController and @RequestMapping annotations. import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; Autowire service class @RestController @RequestMapping("/student/api") public class StudentController { @Autowired private StudentServiceImpl studentService; } · Add the following code in controller class. @PostMapping("/students") public Student createStudent(@Valid @RequestBody Student student) { return studentService.createStudent(student); } · Import the necessary packages for the controller: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; Note: · If error at validation.Vaid statement, then write the dependency in POM.XML <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.0.Final</version> </dependency> · Then import the following package in controller class: import javax.validation.Valid; Note: @PostMapping("/path") @PostMapping("/students") · Annotation for mapping HTTP POST requests onto specific handler methods. · Specifically, @PostMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST). Step 6 and 7: Create Service interface and Service implementation class. under the package: com.example.SpringbootExample.service package com.example.SpringbootExample.service; public interface StudentService { } Write a declaration method createStudent in StudentService interface: public interface StudentService { public Student createStudent(Student student); public List<Student> getAll(); public Optional<Student> getStudent(long id); } Import the model class in StudentService: import com.example.SpringbootExample.model.Student; Create an Implementation class StudentServiceImpl for the StudentService Interface under the same package: package com.example.SpringbootExample.service; import org.springframework.stereotype.Service; @Service public class StudentServiceImpl implements StudentService { } Note: @Service annotation is a specialization of @Component annotation. Spring Service annotation can be applied only to classes. It is used to mark the class as a service provider. Create an autowire object for StudentRepository in StudentServiceImpl: @Autowired private StudentRepository studentRepository; Note: @Autowired: Which marks a constructor, field, setter method, or config method by Spring's dependency injection facilities. Write the implementation for the StudentService interface method: @Override public Student createStudent(Student student) { return studentRepository.save(student); } · createStudent method is calling the save method of JpaRepository by passing the student entity object. Import the necessary packages in StudentService: import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.example.SpringbootExample.model.Student; Step 8: Create a Repository public interface StudentRepository extends JpaRepository<Student, Long> { } Note: StudentRepository extends JpaRepository with Student entity and Long datatype. Note: @Repository annotation is used for indicating that the class provides the mechanism for CRUD operations on objects. Extends the necessary packages in StudentRepository: import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.example.SpringbootExample.demo.model.Student; Run the Application: Right click on main application – SpringbootExampleApplication.java file – Run As – Click on Java Application. Console output: Open POSTMAN Tool: · Select POST method · URL as: localhost:8080 · Provide the URL as localhost:8080/student/api/students · Select raw – and select the Object format as JSON · Enter the data id, firstname and lastname in JSON format { "id": "1", "studentFirstName": "Vishwanath", "studentLastName": "Arabati" } Points on POSTMAN: · Postman is a scalable API testing tool. · API stands for Application Programming Interface. · Allows software applications to communicate with each other via API calls. Reason for POSTMAN: · Accessibility · Use of Collections · Collaboration · Creating Environments · Creation of Tests · Automation Testing · Debugging · Continuous Integration HTTP Requests: · drop-down list of all the HTTP request methods. · GET, DELETE, PATCH, OPTIONS, LINK, POST, COPY, UNLOCK, PURGE, etc. · Mostly used are POST and GET. Request URL or Endpoint · URL option similar like browser URL. · Link to where the API will communicate with. Params · Used to write the parameters of the request. · Parameters includes key values and descriptions. Headers · HTTP request header is the extra data that is required to send along with the request. · Header information is needed for proper two-direction communication between the client and the server. Body · To Specify the data type that needed to send with a request (various types of body data that you can send to match your API). Response section · API responses received from the server. · Generated after you send an API request to the server. GetMapping: · GetMapping for getting all students in controller @GetMapping("/students") public List<Student> getStudents(){ } · getStudents will invoke the service class getAll method to fetch the data and will return: return studentService.getAll(); Student Service Interface method – getting all data public List getAll(); ServiceImple method for getting all students data public List<Student> getAll() { return studentRepository.findAll(); } Service Layer invoking the findAll method of Repository public List<Student> getAll() { return studentRepository.findAll(); } Running the URL from POSTMAN: GetMapping with ID: Controller Code: @GetMapping("/students/{id}") public Optional<Student> getStudentById(@PathVariable long id) { } getStudentById will return: return studentService.getStudent(id); Note: @PathVariable · Annotation which indicates that a method parameter should be bound to a URI template variable. · Supported for RequestMapping annotated handler methods. Service class code: public Optional<Student> getStudent(long id) { } getStudent of Service class will fetch and return to controller: return studentRepository.findById(id); Create ResourceNotFoundException class in com.example.exception packge which extends Exception class public class ResourceNotFoundException extends Exception{ private static final long serialVersionUID = 1L; //Constructor to call super as a method with message of the String public ResourceNotFoundException(String message){ super(message); } } GetMapping by student ID in Controller @GetMapping("/students/{id}") public ResponseEntity getStudentById(@PathVariable(value = "id") Long studentId) throws ResourceNotFoundException { Student student = studentService.findByStudentId(studentId) .orElseThrow(() -> new ResourceNotFoundException("student not found for this id :: " + studentId)); return ResponseEntity.ok().body(student); } Import: import com.example.SpringbootExample.exception.ResourceNotFoundException; Student Service Interface method – get student by ID public Optional findByStudentId(long studentId); Student Service Implementation method – get student by ID public Optional<Student> findByStudentId(long studentId){ return studentRepository.findById(studentId); } Put Mapping by student ID - Student Controller @PutMapping("/students/{id}") public ResponseEntity updateStudent(@PathVariable(value = "id") Long studentId, @Valid @RequestBody Student studentDetails) throws ResourceNotFoundException { Student student = studentService.findByStudentId(studentId) .orElseThrow(() -> new ResourceNotFoundException("Student not found for this id :: " + studentId)); student.setStudentFirstName(studentDetails.getStudentFirstName()); final Student updatedStudent = studentService.save(student); return ResponseEntity.ok(updatedStudent); } Import: import org.springframework.web.bind.annotation.PutMapping; Delete student – student controller @DeleteMapping("/students/{id}") public Map deleteStudent(@PathVariable(value = "id") Long studentId) throws ResourceNotFoundException { Student student = studentService.findByStudentId(studentId) .orElseThrow(() -> new ResourceNotFoundException("Student not found for this id :: " + studentId)); studentService.delete(student); Map response = new HashMap<>(); response.put("deleted", Boolean.TRUE); return response; } Import: import org.springframework.web.bind.annotation.DeleteMapping; import java.util.Map; import java.util.HashMap; Student Service Interface method – delete student public void delete(Student student); Student ServiceImpl method – delete student public void delete(Student student){ studentRepository.delete(student); } Spring Boot Actuator: · Two important aspects of application’s life cycle are Developing and Managing an application. · While pushing the application into production, managing is important. · Must monitor the application at development phase and at the production phase. · Spring Boot provides an actuator dependency that can be used to monitor and manage your Spring Boot application. · Used to monitor and manage the Spring web application. · We can use it to monitor and manage the application with the help of HTTP endpoints or with the JMX. Spring Boot AOP Java application developed and has multiple layers: · Web Layer: showcase with services using the REST or web application. · Business Layer: consists of application business logic. · Data Layer: Application Persistence logic. Cross-cutting concerns: Common aspects such as Logging, Security, validation, caching, etc., · Instead of implementing these concerns in each layer separately Aspect-Oriented Programming (AOP), we implement cross-cutting concerns. · Implement the cross-cutting concern as an aspect. · Aspects will be applied to define pointcuts. AOP · AOP (Aspect-Oriented Programming) is a programming pattern for implementing cross-cutting concerns. · Increases modularity. · Allows separation of the cross-cutting concern. · Cross-cutting concerns are different from the business logic. · Adding extra functionality to existing code without modification of the code. · Spring's AOP framework. · The cross-cutting concern can be modularized into special classes, called aspect. · It is Java implementation. · Compilation process is not needed. · Join points supported only method execution. Aspects Benefits: · Logic for each concern can be placed in one place instead of scattered all over the codebase. · Business modules only contain code for their primary concern (secondary concern has been moved to the aspect). · Responsibility that is to be implemented are called advice. · Aspect's functionality can be implemented into a program at one or more join points. AOP Terminology Aspect: · is a module which encapsulate advice and pointcuts. · provides cross-cutting. · Application consists of any number of aspects. · @Aspect annotation used to implement an aspect using regular class. Pointcut: · is an expression which selects one or more join points. · These join points where advice is executed. · Expressions or patterns are used to define pointcuts. Join point: · is a point in the application where we apply an AOP aspect. · is a specific execution instance of an advice. · Join point can be a method execution, exception handling, changing object variable value, etc. Advice: · The advice is an action that we take either before or after the method execution. · The action is a piece of code that invokes during the program execution. · There are five types of advices in the Spring AOP framework: before, after, after-returning, after-throwing, and around advice. · Advices are taken for a particular join point. Target object: · is object on which advices are applied. · These are always a proxied. · A subclass is created at run time in which the target method is overridden. · Advices are included based on their configuration. Weaving: · Process of linking aspects application types. · We can perform weaving at run time, load time, and compile time. Proxy: · Object that is created after applying advice to a target object. · JDK dynamic proxy implemented by Spring AOP for creating the proxy classes with target classes and advice invocations. · These are called AOP proxy classes. AOP vs. OOP Aspect: A code unit that encapsulates pointcuts, advices, and attributes. Class: A code unit that encapsulates methods and attributes. Pointcut: It defines the set of entry points in which advice is executed. Method signature: It defines the entry points for the execution of method bodies. Advice: It is an implementation of cross-cutting concerns. Method bodies: It is an implementation of the business logic concerns. Waver: It constructs code (source or object) with advice. Compiler: It converts source code to object code. Types of AOP Advices · Before Advice · After Advice · Around Advice · After Throwing · After Returning Before Advice: advice which executes before a join point. @Before annotation. After Advice: advice which executes after a join point. @After annotation. Around Advice: advice which executes before and after of a join point. After Throwing Advice: advice which executes when a join point throws an exception. After Returning Advice: advice which executes when successfull method executes. · Add Spring AOP dependency in the pom.xml file before AOP implementation. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.2.2.RELEASE</version> </dependency> Login and Registration REST API with Spring Security Example: Spring Boot REST application consists of two web services - user registration and user login. Login and Registration REST API with Spring Security Table of Content 1. Create a Spring Boot Starter Project 2. Maven Dependency 3. Configure in the application.properties file 4. Create entity class 5. Create a repository 6. Create a service 7. Create a DTO class 8. Create a Controller class 9. Create a Spring Security Config class 10. Spring Application Insert data 11. Run the Application Create entity class Role.java package com.example.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="roles") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; public Role() { } 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; } } User.java package com.example.entity; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; @Entity @Table(name="users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; @Column(nullable = false, unique = true) private String userName; @Column(nullable = false, unique = true) private String email; @Column(nullable = false) private String password; @ManyToMany @LazyCollection(LazyCollectionOption.FALSE) private Set<Role> roles; 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; } public String getUserName() { return userName; } public void setUserName(String username) { this.userName = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } } Create a repository RoleRepository.java package com.example.repository; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import com.example.entity.Role; public interface RoleRepository extends JpaRepository<Role, Integer> { Optional<Role> findByName(String name); } UserRepository.java package com.example.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.example.entity.User; public interface UserRepository extends JpaRepository<User, Integer> { User findByUsernameOrEmail(String username, String email); } Create a service UserDetail.java package com.example.service; import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; 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.example.entity.User; import com.example.repository.UserRepository; @Service public class UserDetail implements UserDetailsService { @Autowired UserRepository userRepo; @Override public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException { User user = userRepo.findByUserNameOrEmail(username, username); if(user==null){ throw new UsernameNotFoundException("User not exists by Username"); } Set<GrantedAuthority> authorities = user.getRoles().stream() .map((role) -> new SimpleGrantedAuthority(role.getName())) .collect(Collectors.toSet()); return new org.springframework.security.core.userdetails.User (username,user.getPassword(),authorities); } } Create a DTO class LoginDto.java package com.example.dto; public class LoginDto { private String username; private String password; public LoginDto() { } 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; } } SignUpDto.java package com.example.dto; public class SignUpDto { private String name; private String username; private String email; private String password; public SignUpDto() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } Create a Controller class HomeController.java package com.example.controller; import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.dto.LoginDto; import com.example.dto.SignUpDto; import com.example.entity.Role; import com.example.entity.User; import com.example.repository.RoleRepository; import com.example.repository.UserRepository; @RestController @RequestMapping("/api") public class HomeController { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserRepository userRepository; @Autowired private RoleRepository roleRepository; @Autowired private PasswordEncoder passwordEncoder; @PostMapping("/login") public ResponseEntity<String> authenticateUser(@RequestBody LoginDto loginDto) { Authentication authentication = authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword())); SecurityContextHolder.getContext().setAuthentication(authentication); return new ResponseEntity<>("User login successfully!...", HttpStatus.OK); } @PostMapping("/signup") public ResponseEntity<?> registerUser(@RequestBody SignUpDto signUpDto){ // checking for username exists in a database if(userRepository.existsByUserName(signUpDto.getUsername())){ return new ResponseEntity<>("Username is already exist!", HttpStatus.BAD_REQUEST); } // checking for email exists in a database if(userRepository.existsByEmail(signUpDto.getEmail())){ return new ResponseEntity<>("Email is already exist!", HttpStatus.BAD_REQUEST); } // creating user object User user = new User(); user.setName(signUpDto.getName()); user.setUserName(signUpDto.getUsername()); user.setEmail(signUpDto.getEmail()); user.setPassword(passwordEncoder.encode(signUpDto.getPassword())); Role roles = roleRepository.findByName("ROLE_ADMIN").get(); user.setRoles(Collections.singleton(roles)); userRepository.save(user); return new ResponseEntity<>("User is registered successfully!", HttpStatus.OK); } } Create a Spring Security Config class SecurityConfig.java package com.example.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public static PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { return configuration.getAuthenticationManager(); } @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests().antMatchers("/api/**", "/h2-console/**").permitAll() .anyRequest().authenticated(); http.headers().frameOptions().disable(); return http.build(); } } Insert data using SpringBootApplication class package com.example; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import com.example.entity.Role; import com.example.repository.RoleRepository; @SpringBootApplication public class LoginRegistrationRestApiSpringSecurityApplication { public static void main(String[] args) { SpringApplication.run(LoginRegistrationRestApiSpringSecurityApplication.class, args); } @Bean public CommandLineRunner demo(RoleRepository roleRepo) { return (args) -> { Role role=new Role(); role.setName("ROLE_ADMIN"); roleRepo.save(role); }; } } Run the Application Spring Data JPA @Query Example1: @GetMapping("get/desc") public List<StudentEntity> getStudentOrderDesc(){ return studentService.sortByName(); } public List<StudentEntity> sortByName(){ return studentRepo.findAndOrderByName(); } @Query(value="select * FROM student order by name desc", nativeQuery = true) List<StudentEntity> findAndOrderByName(); @Query: · Annotation to declare finder queries directly on repository methods. · Use method with @Query annotation for defining SQL to execute for a Spring Data repository method. · Value attribute contains the JPQL or SQL to execute. · The @Query annotation takes precedence over named queries. · Place a query definition above the repository layer methods, rather than inside our domain model as named queries. · Because the repository is responsible for persistence. JPQL Example: · By default, the query definition uses JPQL. @Query("select s from student s where s.code = 1") Collection<Student> findAllActiveStudents(); · Using JPQL query definition Spring Data can handle sorting without any problem. · Only we need to add a method parameter of type Sort: @Query(value = "select s from StudentEntity s") List<User> findAllStudents(Sort sort); · Invoke this method and pass a Sort parameter, to order the result by the name property of the StudentEntity object: studentRepository.findAllStudents(Sort.by("name")); Example: @GetMapping("get/desc") public List<StudentEntity> getStudentOrderDesc(){ return studentService.sortByName(); } public List<StudentEntity> sortByName(){ return studentRepo.findAndOrderByName(Sort.by("name")); } @Query(value="select s FROM StudentEntity s") List<StudentEntity> findAndOrderByName(Sort sort); Native Example: · Native SQL to define query with which we can set the value of the nativeQuery attribute to true so that we can define the native SQL query in the value attribute of the annotation: @Query( value = "select s from student s where s.code = 1", nativeQuery = true) Collection<Student> findAllActiveStudentsNative(); Example2: Named Parameters @GetMapping("/getName/{name}") public List<StudentEntity> getStudent(@PathVariable(value = "name") String name) throws ResourceNotFoundException{ return studentService.findByName(name); } public List<StudentEntity> findByName(String str){ return studentRepo.findByName(str); } @Query(value="select * FROM student where name=:name", nativeQuery = true) List<StudentEntity> findByName(@Param("name") String name); Java 8 Stream API · Java stream API belongs to java.util.stream which consists of classes, interfaces, and an enum to allows functional-style operations on the elements. · Stream API makes wide range of use of built-in functional interfaces. · Java 8 stream is a sequence of data. · Stream helps in performs data operations. · Performing data operations can be such as Collections, Arrays or I/O channels. · Two types of Stream: o Sequential o Parallel. · Java 8 Collections interface has been added two new methods stream() and parallelStream() for supporting data operations obtained from collections. · List, Set, Deque, and Queue interface extends the Collection interface. · So we can get a stream or a parallel stream from the collection classes which implement these interfaces. · Common source of streams is collection objects such as sets, maps, and lists. Stream API Characteristics: · Create a stream from a source for performing operations and produce the result. · Source may be a collection or an array or an I/O resource. · Stream never modifies the source nor store the data (only performs operations on the data). · We can’t add or remove elements from streams. · Streams are not data structures. · Stream’s operations are two categories: Intermediate operations & Terminal operations. · Stream works on a ‘Pipeline of Operations’ concept. · A pipeline of operations consists: 1. a source, 2. zero or more intermediate operations and 3. a terminal operation. · For better performance in case of dealing with large data, Stream has a concept of parallel processing without writing any multithreaded code. · All elements of a stream are not populated at a time. · Elements are populated on-demand basis. · Intermediate operations are not performed until terminal operation is called. · Streams can’t use the same stream more than once. · If we use the stream first time, it is said to be consumed. Creating Stream: 1) Using Stream.of() method o Consists of variable argument list of elements: static <T> Stream<T> of(T… values) Examples: Stream<String> streamOfStrings = Stream.of("Sunday", "Monday", "Wednesday", "Friday"); Stream<Integer> streamOfIntegers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9); · Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9}; · Stream<Integer> streamOfArrayOfIntegers = Stream.of(array); 2) Stream from a Collection using stream() & parallelStream() methods o java.util.Collection interface has stream() and parallelStream() methods for creating sequential and parallel streams. o These methods return invoked collection elements. List<String> list = Arrays.asList("https://","vishwaeduit", "dot", "com"); //creating a list //OR //creating a list using of() of JDK 9 List<String> list = List.of("https://","vishwaeduit", "dot", "com"); // creating a sequential stream (used most of the time) Stream<String> streamofStrings = list.stream(); // creating a parallel stream Stream<String> streamofStrings = list.parallelStream(); 3) Stream from an Array using Arrays.stream() o Create Array using stream() method of java.util.Arrays. String[] arr= new String[] { "a", "b", "c" }; Stream<String> streamOfStrings = Arrays.stream(arr); Stream.of() and Arrays.stream()methods for creating a sequential stream from a specified array. Both methods return a Stream when invoked with a non-primitive type T. 4) Stream using Stream.builder() · Stream can be created using builder() method. · In order to get a stream builder, call the static builder() method. · returns an object of type java.util.stream.Stream.Builder. Builder<String> builder = Stream.<String>builder(); // creating a builder builder.add("a").add("b").add("c"); // adding elements Stream<String> s = builder.build(); // creating stream The above code can be reduced (one-liner): Stream<String> s = Stream.<String>builder().add("a").add("b").add("c").build(); 5) Creating an Empty Stream using Stream.empty() · Which does not contain any elements. · empty() method is belongs to java.util.stream.Stream interface. · empty is a static method. · returns a stream object with no elements. · Is for avoiding returning null for streams with no element. · Empty stream is generally used to return an object from a method that returns a stream instead of returning null so as to avoid NullPointerException. Stream<String> emptyStream = Stream.empty(); 6) Creating an infinite Stream using Stream.generate() method · Which accepts a Supplier for generating elements and results as on infinite stream. · For restricting it, specify the desired size or the generate() method will work until it reaches the memory limit. · Example: code generates a stream of 5 integers. Random random = new Random(); Stream<Integer> stream = Stream.generate( () -> {return random.nextInt(100);} // generating random numbers between 0 and 99 ).limit(5); · generate() accepts an argument of type java.util.function.Supplier which is a functional interface and hence we can implement it using a Lambda expression. 7) Creating an infinite Stream using Stream.iterate() method Example: if we want to create a stream of odd numbers,: Stream<Integer> streamOfOddNumbers = Stream.iterate(1, n -> n + 2); · iterate() takes a starting value as the first parameter. · Another parameter is a lambda expression that gets passed the previous value and generates the next value. · The next value after 1 will be 3 in the example. · It will produce odd numbers as long as you need them. 8) Creating Stream of a File · Java NIO class Files (java.nio.file.Files) allows for generating a Stream<String> of a text file through its static method lines(). · Every line of the text becomes an element of the stream. · This stream iterates for reading the file contents line by line. Stream<String> streamOfStrings = Files.lines(Paths.get(filePath)); // Generating Stream from a File streamOfStrings.forEach((line) -> System.out.println(line)); // Printing contents of the File Modifier and Type Method and Description boolean allMatch(Predicate<? super T> predicate) Returns whether all elements of this stream match the provided predicate. boolean anyMatch(Predicate<? super T> predicate) Returns whether any elements of this stream match the provided predicate. static <T> builder() Stream.Builder<T> Returns a builder for a Stream. <R,A> R collect(Collector<? super T,A,R> collector) Performs a mutable reduction operation on the elements of this stream using a Collector. <R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) Performs a mutable reduction operation on the elements of this stream. static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. long count() Returns the count of elements in this stream. Stream<T> distinct() Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream. static <T> Stream<T> empty() Returns an empty sequential Stream. Stream<T> filter(Predicate<? super T> predicate) Returns a stream consisting of the elements of this stream that match the given predicate. Optional<T> findAny() Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. Optional<T> findFirst() Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper) Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper) Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper) Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper) Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. void forEach(Consumer<? super T> action) Performs an action for each element of this stream. void forEachOrdered(Consumer<? super T> action) Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order. static <T> Stream<T> generate(Supplier<T> s) Returns an infinite sequential unordered stream where each element is generated by the provided Supplier. static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc. Stream<T> limit(long maxSize) Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. <R> Stream<R> map(Function<? super T,? extends R> mapper) Returns a stream consisting of the results of applying the given function to the elements of this stream. DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream. IntStream mapToInt(ToIntFunction<? super T> mapper) Returns an IntStream consisting of the results of applying the given function to the elements of this stream. LongStream mapToLong(ToLongFunction<? super T> mapper) Returns a LongStream consisting of the results of applying the given function to the elements of this stream. Optional<T> max(Comparator<? super T> comparator) Returns the maximum element of this stream according to the provided Comparator. Optional<T> min(Comparator<? super T> comparator) Returns the minimum element of this stream according to the provided Comparator. boolean noneMatch(Predicate<? super T> predicate) Returns whether no elements of this stream match the provided predicate. static <T> Stream<T> of(T... values) Returns a sequential ordered stream whose elements are the specified values. static <T> Stream<T> of(T t) Returns a sequential Stream containing a single element. Stream<T> peek(Consumer<? super T> action) Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream. Optional<T> reduce(BinaryOperator<T> accumulator) Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any. T reduce(T identity, BinaryOperator<T> accumulator) Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner) Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions. Stream<T> skip(long n) Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. Stream<T> sorted() Returns a stream consisting of the elements of this stream, sorted according to natural order. Stream<T> sorted(Comparator<? super T> comparator) Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator. Object[] toArray() Returns an array containing the elements of this stream. <A> A[] toArray(IntFunction<A[]> generator) Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing. Array List Example: List<String>languages = new ArrayList <String>(); languages.add("English"); languages.add("German"); languages.add("French"); If we need to print the list of members, Using For loop: For(String language:languages){ System.out.println(language); } Usage of Stream API Methods: · Obtain the stream by calling the .stream() method on the languages array list and printing using Stream API. Languages.stream().forEach(System.out::println) · After getting the stream, we invoke forEach() method and pass the action which takes on each Element, then print the member value on the console using the System.out.println method. · After getting a stream from a collection, we can use that stream to process the collection’s elements. Example: package com; import java.util.ArrayList; import java.util.List; class Student{ int id; String name; int marks; public Student(int id, String name, int marks) { this.id = id; this.name = name; this.marks = marks; } } public class StreamExample { public static void main(String[] args) { List<Student> studentsList = new ArrayList<Student>(); //Adding Products studentsList.add(new Student(1,"abcd",100)); studentsList.add(new Student(2,"xyz",98)); studentsList.add(new Student(3,"pqr",85)); studentsList.add(new Student(4,"mnop",77)); studentsList.add(new Student(5,"asdf",68)); /*Obtain the stream by calling the .stream() method on the languages array list and printing using Stream API. Languages.stream().forEach(System.out::println) After getting the stream, we invoke forEach() method and pass the action which takes on each Element, then print the member value on the console using the System.out.println method. After getting a stream from a collection, we can use that stream to process the collection’s elements. */ studentsList.stream() .filter(p ->p.marks> 80) .map(pm ->pm.marks) .forEach(System.out::println); } } stream.Filter(): · Used to filter a stream. stream.filter(item->item.startsWith("E")); · filter() method consists of a predicate as a parameter. · Predicate interface contains boolean test(T t) which have a parameter and returns boolean value. · So, lambda expression (item->item.startsWith("E")) to the test() function. · When the filter() method is called on a stream, the filter passed as a parameter to the filter() function is stored internally. stream.sort(): · sort() method is for sorting the stream. languages.stream().sorted().forEach(System.out::println); · for sorting the elements in alphabetical order. stream.map(): · map() method for mapping the elements of a stream into another new object. language.stream().map(item->item.uppercase().forEach(System.out::println)); · This map all the elements that are strings in the language collection to their uppercase. stream.collect(): · collect() method to process on the stream interface. · When the collect() method is called, filtering and mapping will occur. · The object obtained from those actions will be collected. List<String> ucaselanguage = languages.stream().map(item>item.toUpperCase()).collect(collectors.toList())); System.out.println(ucaselanguage); · Initially, it creates a stream. · Then adds a map to convert the strings to uppercase. · and collects all objects in a new list. stream.min() & max(): · Stream API gives the min() and max() methods for finding the min & max values in streams respectively. · These will help to find min and max in different streams such as streams of chars, strings, dates, etc. · Changes needs to done in the parameter when we pass in this method based on the stream type. Example: max(Comparator. comparing (Integer::value of)) · For getting stream of numbers max value · Comparator used. · comparing() method for comparing elements of the stream. · and same method is used for comparing elements of all types of streams, such as stream of chars, Strings, etc. Example: //Getting max number Integer maximum = Stream.of(10,13,4,9,2,100).max(Comparator.comparing(Integer::valueOf)).get(); //Getting min number //getting max number Integer minimum = Stream.of(10,13,4,9,2,100).min(Comparator.comparing(Integer::valueOf)).get(); System.out.println("Max number is: "+maximum); System.out.println("Min number is: "+minimum); stream.count(): · Count method of Stream API returns the number of elements in the stream after filtering. · For getting the count of languages starting with ‘G.’ long count = languages.stream().filter(item->item.getName().startsWith(‘G’)).count(); · count() method returns a long (i.e count of elements matching the filter condition). package com.vishwaeduit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class StatefulExample { public static void main(String[] args) { List<Integer> ss = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); List<Integer> result = new ArrayList<Integer>(); Stream<Integer> stream = ss.parallelStream(); stream.map(s -> { synchronized (result) { if (result.size() < 10) { result.add(s); } } return s; }).forEach( e -> {}); System.out.println(result); } } CommandLineRunner is a Spring Boot interface. Console application consists of a main class, SpringBootConsoleApplication.java. which starter of Spring Boot console application. Use @SpringBootApplication annotation on main class to enable auto-configuration This main class can be Implemented with CommandLineRunner interface. CommandLineRunner is a Spring Boot interface. this interface has a run method. Spring Boot will implicitly invoke the run method of all beans implementing this interface after the application context has been loaded. Named Query Example: public class SpringBootConsoleApplication implements CommandLineRunner { ..... } public class SpringBootConsoleApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(SpringbootExampleApplication.class, args); } Example: run method @Override public void run(String... args) throws Exception { for(int i=1;i<=5;i++) { System.out.println(i); } } Spring Boot CLI (Command Line Interface) is a command line software or tool. This CLI tool is provided by the Spring framework for quickly developing and testing Spring Boot applications from the command prompt. SpringBootConsoleApplication run method code: @Override public void run(String... args) throws Exception { Student student = new Student(); List<Student> stud= studentRepository.findByLastName("Arabati"); System.out.println(stud); } Student Entity Code: @Entity @NamedQuery(name = "Student.findByLastName", query = "select s from Student s where s.studentLastName = ?1") @Table(name = "student") public class Student { private int studentID; private String studentFirstName; private String studentLastName; //getters and setters //toString() to print id, firstname, lastname //Constructors } Repository interface Code: @Repository public interface StudentRepository extends JpaRepository { List findByLastName(String studentLastName); } POINTS on Springboot and Micro Services: · Micro Service architecture allows to develop and deploy services alone. · These services will have own process. · Services process are lightweight model for supporting business applications. · It is Service Oriented Architecture. · Microservice architecture consists of number of microservices. · All microservices, by integrating and constructs a big service. · In the microservice architecture, all the services communicate with each other. · Microservices exposed by REST. · Microservices are deployable units. · Microservices are cloud-enabled. · Microservices for building an application from a set of smaller services. · Web services are like programmable components which can communicate with each another by internet channel. · Microservices and web services share similarities but are different in purpose and implementation. · Microservices benefits include scalability, modularity, ease of maintenance, resiliency, speed of deployment. · Microservices drawbacks are complexity of program, testing, security, deployment. · Web service benefits are interoperability, ease of integration, cost. · Drawbacks of web services are security, performance bottlenecks, complexity. · Microservices refer to an architectural style where applications are decomposed into small, independent services. · These services are loosely coupled. · These serves communicate with each other through APIs. · Each microservice can handles a specific business capability. · REST APIs are used as the communication mechanism between different microservices in a Microservices architecture. · Microservices expose their functionalities as RESTful APIs, allowing other microservices or external systems to interact with them. · Microservices can be without REST Services: RESTful APIs are commonly used in Microservices architectures, other communication protocols can also be employed, such as messaging queues or event-driven mechanisms. · REST APIs are not a mandatory requirement for implementing Microservices. · Microservices Architecture provides benefits such as improved scalability, flexibility, independent service development and deployment, fault isolation, technology diversity, and increased team autonomy. · It enables faster development cycles, supports continuous deployment, and allows teams to work on different services simultaneously. BACK