CS F213 Objected Oriented Programming Labsheet 13
Java Spring Boot
Spring Boot is an open source Java-based framework used to create a micro Service. It provides a good platform for Java developers to develop a stand-alone and production-grade spring application that you can just run. You can get started with minimum configurations without the need for an entire Spring configuration setup.
How does it work?
Spring Boot automatically configures your application based on the dependencies you have added to the project by using @EnableAutoConfiguration
annotation. For example, if MySQL database is on your classpath, but you have not configured any database connection, then Spring Boot auto-configures an in-memory database.
The entry point of the spring boot application is the class contains @SpringBootApplication
annotation and the main method.
Spring Boot automatically scans all the components included in the project by using @ComponentScan
annotation.
Spring Boot Starters
Handling dependency management is a difficult task for big projects. Spring Boot resolves this problem by providing a set of dependencies for developers convenience.
Spring Boot Starter Actuator dependency is used to monitor and manage your application.
Spring Boot Starter Security dependency is used for Spring Security.
Spring Boot Starter web dependency is used to write a Rest Endpoints.
How to setup?
Create and Setup Spring Boot Project in Spring Tool Suite
Go to https://start.spring.io/
Select Maven as Project builder
Select Java as language
Name the project something if you want and let other fields untouched
Now click on 'Add Dependencies' and add 'Spring web'
Click on 'Generate' to download the .zip file
Install and run Your First Spring Boot Application in IntelliJ IDEA
You can skip most of the above steps and use Intellij IDEA to directly start a Spring Boot project as well
Go to https://www.jetbrains.com/idea/download/
Download and install the IDE on your system
Extract the downloaded Spring boot zip file
Click on Open an existing project in IntelliJ and browse to the
pom.xml
fileClick on import changes on prompt and wait for the project to sync.
How to run?
Go to src->main->java->com.example.demo->DemoApplication.java
To run this application now Right-click on the DemoApplication.java > Run “DemoApplication.main()”
Or, you can click the 'Play' button on the toolbar to start the application.
Write a Rest Endpoint
Create a new file in the src folder (call it MainController.java
for example) and follow the steps shown below −
Firstly, add the
@RestController
annotation at the top of the class.Now, write a Request URI method with
@RequestMapping
annotation.Then, the Request URI method should return the Hello World string
So now the main file will look like :
Now run the project and open a browser and type localhost:8080
to see the output of your endpoint.
Now let's create a new endpoint in a different path say /test. Have a look at the following code:
Add this snippet to the MainController.java
file and rerun the project. After that go to http://localhost:8080/test and observe the output
Note: The default port of the Tomcat server is 8080 and can be changed in the application.properties file. Example:
server.port=7000
By following the above steps, we have created a simple RESTful
route with some messages in it. In order to make a more complex application, more RESTful routes are added to perform the CRUD
operations on the server.
Spring Boot Annotations
Spring Boot Annotations are a form of metadata that provides data about a spring application. Spring Boot is built on the top of the spring and contains all the features of spring. Annotations are used to provide supplemental information about a program.
Spring annotations present in the org.springframework.boot.autoconfigure
and org.springframework.boot.autoconfigure.condition
packages are commonly known as Spring Boot annotations.
@SpringBootApplication
Annotation : This annotation is used to mark the main class of a Spring Boot application. It encapsulates @SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan annotations with their default attributes.@Controller
Annotation: This annotation provides Spring MVC features. It is used to create Controller classes and simultaneously it handles the HTTP requests. Generally we use @Controller annotation with @RequestMapping annotation to map HTTP requests with methods inside a controller class.@RestController
Annotation: This annotation is used to handle REST APIs such as GET, PUT, POST, DELETE etc. and also used to create RESTful web services using Spring MVC. It encapsulates @Controller annotation and @ResponseBody annotation with their default attributes.@RequestMapping
Annotation: This annotation is used to map the HTTP requests with the handler methods inside the controller class.
Example
For handling specific HTTP requests we can use
@GetMapping @PutMapping @PostMapping @PatchMapping @DeleteMapping
NOTE : We can manually use GET, POST, PUT and DELETE annotations along with the path as well as we can use @RequestMapping annotation along with the method for all the above handler requests
@RequestBody
Annotation: This annotation is used to convert HTTP requests from incoming JSON format to domain objects directly from the request body. Here, the method parameter binds with the body of the HTTP request.@ResponseBody
Annotation: This annotation is used to convert the domain object into HTTP request in the form of JSON or any other text. Here, the return type of the method binds with the HTTP response body.
Typical Layout
We are going to create packages to make sure we use them to make our file tree better to read and interpret. We’ll mostly use the following packages
and create classes and interfaces in these packages
controller
: It will contain all classes and interfaces related to controllers.dao
: It will contain all the repositories-related interfaces and classes.service
: It will contain all the business logic-related interfaces and classes.model
: It will contain all the models in form of classes.exceptions
: It will contain all the custom exceptions
Building RESTful Web Services
Let's create a package called controller
and model
. In the model package we will create a new class Product.java
with Name, ID, getter and setter methods.
Now we will create four APIs in controller
package with ProductServiceController.java
GET API -
The default HTTP request method is GET. This method does not require any Request Body. You can send request parameters and path variables to define the custom or dynamic URL.
The sample code to define the HTTP GET request method is shown below. In this example, we used HashMap to store the Product. Note that we used a Product.java class as the product to be stored.
Here, the request URI is /products and it will return the list of products from HashMap repository. The controller class file is given below that contains GET method REST Endpoint.
For the rest three APIs only the main code will be given, the header packages are same as GET API
POST API
The HTTP POST request is used to create a resource. This method contains the Request Body. We can send request parameters and path variables to define the custom or dynamic URL.
The following example shows the sample code to define the HTTP POST request method. In this example, we used HashMap to store the Product, where the product is a Product.java class.
Here, the request URI is /products, and it will return the String after storing the product in the HashMap repository.
PUT API
The HTTP PUT request is used to update the existing resource. This method contains a Request Body. We can send request parameters and path variables to define the custom or dynamic URL.
The example given below shows how to define the HTTP PUT request method. In this example, we used HashMap to update the existing Product, where the product is a Product.java class.
Here the request URI is /products/{id} which will return the String after a the product into a HashMap repository. Note that we used the Path variable {id} which defines the products ID that needs to be updated.
DELETE API
The HTTP Delete request is used to delete the existing resource. This method does not contain any Request Body. We can send request parameters and path variables to define the custom or dynamic URL.
The example given below shows how to define the HTTP DELETE request method. In this example, we used HashMap to remove the existing product, which is a Product.java class.
The request URI is /products/{id} and it will return the String after deleting the product from HashMap repository. We used the Path variable {id} which defines the products ID that needs to be deleted.
Combine all the APIs into one file ProductServiceController.java
How to check your APIs
Install Postman
Go to https://www.postman.com/downloads/
Download and Install it on your machine
Run your Spring boot project
Go to new and select
HTTP
Test APIs
Send
GET
from the dropdown menu and type http://localhost:8080/products in the urlClick on
Send
If everything is followed, the following output will be received
This is what we added in our HashMap at the very start.
To check POST API, create a new request
Select
Post
from the dropdown and go to theBody
tab thenraw
to give your request a body.Let's give a new Product in JSON format
put the same URL http://localhost:8080/products in the URL box and click
send
The output will be
Product is created successfully
Try performing GET again to see the added product.
To check PUT API, again create a new request and select PUT from menu, and type http://localhost:8080/products/3 in url section where 3 is the id of product we want to update
In the body, again in raw->Json type the name of updated product
{ "name":"Potato" }
Click 'Send'
You should get
Product is updated successsfully
Now if you use GET request, you will get the following output
To check Delete API create a new request of Delete type and type http://localhost:8080/products/1 where 1 is the ID of the product you want to delete
Click on 'Send'
You should get
Product is deleted successsfully
Conclusion
Now you know how you can create different RESTful APIs. Here we used 2 end points one was /products
and another was /products/{id}
. This was because we needed id parameter to implement update and delete functionality. Similarly you can create two endpoints say /borrow
and /return
for a library management system and implement different APIs in that. This is basically how CRUD operations happen in JAVA Spring boot.
Further we can connect it to a database, so for that say we are implementing POST API then we need to create a new row in the table of Products in our database everytime. Also we can make a front-end through HTML/CSS or Java Swing and connect it to Spring boot backend which we made so as to perform these CRUD operations on our browser instead of Postman.
Java Optional Class
Java’s Optional class was introduced in 2014 to allow developers to represent the empty state. In Java we create an Optional with a specific state. At the point of creation we either give it an object, or don’t give it an object.
Here’s how to create an Optional which contains an object.
Creating an Optional which doesn’t contain an object is even simpler.
Need of Optional
You’re coding a REST API. Right now, you need to create a Java method which searches by the guitarist’s last name.
You add this method to the GuitaristService
class. Right now it only supports a single guitarist. It looks up the guitarist and returns it, if found.
But what if the guitarist doesn’t exist? In this scenario, you think the best thing to do is to return null
.
So a chance of NullPointerException
is there. Even worse would be if we had to access some fields of the guitarist object. Since the guitarist is null, Java throws a NullPointerException
and whoever is calling our REST API gets a 500
error.
Instead of thinking hard to handle null, we can use the Optional class.
If lastName is Hendrix, we construct a Guitarist object and pass it to
Optional.of
. This creates an Optional containing the Guitarist, which we return from the method.If lastName is anything else, we return
Optional.empty()
. This creates an empty Optional, which will force whoever is calling the method to handle the guitarist not found scenario, as you’ll see shortly.
How to handle an Optional returned by a method?
The ifPresent
method takes a consumer function, passed as a lambda expression
. The function gets executed if the Optional contains a value. That’s perfect for when we want to handle the value in some way. And we don’t even have to use an if statement.
Another way can be
Substituting a default value
Java Streams
Stream represents a sequence of objects from a source, which supports aggregate operations. It is a new abstract layer introduced in Java 8. Using stream, you can process data in a declarative way.
Generating Streams in Java
Collection interface has two methods to generate a Stream.
stream()
− Returns a sequential stream considering collection as its source.parallelStream()
− Returns a parallel Stream considering collection as its source.
Important Operations
forEach
Method: Stream has provided a new method 'forEach' to iterate each element of the stream. The following code segment shows how to print 10 random numbers using forEach.
2.map
Method: The 'map' method is used to map each element to its corresponding result. The following code segment prints unique squares of numbers using map.
filter
Method: The 'filter' method is used to eliminate elements based on a criteria. The following code segment prints a count of empty strings using filter.
limit
Method: The 'limit' method is used to reduce the size of the stream. The following code segment shows how to print 10 random numbers using limit.
sorted
Method: The 'sorted' method is used to sort the stream. The following code segment shows how to print 10 random numbers in a sorted order.
Parallel
Processing: parallelStream is the alternative of stream for parallel processing. Take a look at the following code segment that prints a count of empty strings using parallelStream.
It is very easy to switch between sequential and parallel streams.
Collectors
: Collectors are used to combine the result of processing on the elements of a stream. Collectors can be used to return a list or a string.
8.Statistics
: With Java 8, statistics collectors are introduced to calculate all statistics when stream processing is being done.
Example
Output
Last updated