Back-end programming
Spring Boot
Enterprise applications
Enterprise applications
Enterprise software is computer software used to support the operational and strategic needs of an organisation rather than individual users.
Java ENTERPRISE EDITION
Java EE (currently known as Jakarta EE) provides a platform that makes enterprise applications easy to write.
The Java EE server provides several services in the form of a container, that manage transaction handling, database connection, state management, and multithreading, without us having to explicitly handwrite every single line of code.
Why USE A FRAMEWORK?
- Helps focus on the core task rather than the boilerplate
- Helps us adhere to the industry and regulatory standards
- Brings down the total cost of ownership for the application
Enterprise application frameworks
SPRING
Spring Framework
Spring framework is divided into modules, which makes it faster and easier to choose the parts to use in any application.
Spring Ecosystem
spring core
The central part of the Spring Framework. Its core technologies are:
- Inversion of Control
- Dependency Injection
- Spring Beans
- Spring Expression Language (SpEL)
- Spring Context
Inversion of control
IoC is a principle in software development which transfers the control of objects to a container or framework.
The framework takes control of the flow of a program and make calls to our custom code.
Dependency Injection is an example of how we can achieve IoC.
dependency injection
Any Java application is composed of a number of objects that collaborate with each other. This collaboration is possible due to objects having dependencies on each other.
Dependency injection is a pattern used to implement IoC.
A given class or system is no longer responsible for instantiating their own dependencies; this is done by an assembler/DI tool.
spring container
An IoC container is a common characteristic of frameworks that implement IoC.
In Spring, it is represented by the interface ApplicationContext.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
The Spring framework provides several concrete implementations of said interface.
spring container
In order to assemble beans, the container uses configuration metadata, which can be in the form of XML configuration or annotations.
But what are Spring Beans?
Spring beans
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans.
Configuration - Bean creation
<!-- In the XML file-->
<bean id="myBean" class="com.mindera.mindswap.MyClass"/>
// In Main class
public class Main {
public static void main(String[] args){
(...)
MyClass myClass = context.getBean("myBean", MyClass.class);
myClass.doSomething();
}
}
Configuration - Dependency injection
<!--Constructor-based DI-->
<bean id="myBean" class="com.mindera.mindswap.MyClass"/>
<bean id="myBeanWithDependencies" class="com.mindera.mindswap.MyOtherClass">
<constructor-arg name="myclass" ref="myBean"/>
</bean>
<!--Setter-based DI-->
<bean id="myBean" class="com.mindera.mindswap.MyClass"/>
<bean id="myBeanWithDependencies" class="com.mindera.mindswap.MyOtherClass">
<property name="myclass" ref="myBean"/>
</bean>
There are two major ways of injecting dependencies with Spring: constructor-based DI and setter-based DI.
Live Coding
Spring Application
SPRING BOOT
What is SPRING BOOT?
Spring Boot is an opinionated, convention-over-configuration-focused addition to the Spring framework.
It eliminates the boilerplate configurations required for setting up a Spring application, making it easy to create them.
Spring Boot Features
- Create stand-alone Spring applications.
- Embed web container directly, without the need to deploy WAR files.
- Provide starter dependencies to simplify the build configuration
- Automatically configure Spring functionality, whenever possible
- No requirement for XML configuration
- Metrics, health-checks, and externalised configuration
Spring initializr
start.spring.io allows us to generate JVM-based projects quickly.
We can customise the project to generate:
- the build system and packaging
- the language
- the coordinates
- the platform version
- the dependencies
Live coding
Spring Initializr
Web Applications
with spring boot
Web Application
A software program that runs on a web server. It is accessible through a browser.
Java provides support for web application through Servlets and JSPs.
The web application and its components are managed and executed inside a web container (aka servlet container).
Servlet
A servlet is a core class in web applications. They either respond to HTTP requests directly, or delegate that work to some other part of the application.
Servlets run in a servlet container.
tomcat
Tomcat is a Web Application Container used to deploy applications built using the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies.
It handles the networking side, i.e., parsing requests, handling connections, etc.
By default, Spring Boot provides an embedded Apache Tomcat build.
JSP
JSP is a server-side programming technology that allows Java code to be embedded in HTML pages.
The Java code is executed on the server and compiled with the JSP to produce a plain, browser-readable HTML page.
SPRING MVC
Spring MVC is a higher level abstraction built on top of Java Servlets, and based on the Model-View-Controller pattern.
Servlets are replaced with controllers.
Front Controller receives the request and delegates it to the appropriate Controller.
SPRING CONTROLLER
When our application receives a GET request with the URL <app_domain>/hello, the FrontController will forward this request to the MyController servlet class.
// SPRING SCANS YOUR CODE FOR @Controller ANNOTATIONS
@Controller
public class MyController {
// @GetMapping MAPS HTTP GET REQUESTS ONTO SPECIFIC HANDLER METHODS
@GetMapping("/hello")
public String homePage(Model model) {
model.addAttribute("hello", "This is me, saying hello.");
// RETURNING THE VIEW
return "home";
}
}
SPRING MODEL
The Spring Model can supply attributes that will be later used for rendering views. To provide a view with usable data, we simply add it to its Model object.
@Controller
public class MyController {
@GetMapping("/user")
public String userDetails(Model model) {
// CREATE USER OBJECT
User user = new User("Dave Bayley", "davebayley89@gmail.com");
// ADD USER OBJECT AS ATTRIBUTE; DATA WILL BE ACCESSIBLE IN VIEW
model.addAttribute("user", user);
// RETURN USER VIEW
return "user";
}
}
Data can be added to the Spring model inside the controller using the Model or ModelAndView classes.
VIEW RESOLVER
The ViewResolver interface provides a mapping between view names and the actual view objects.
// IN THE application.properties FILE
spring.mvc.view.prefix=/templates
spring.mvc.view.suffix=.jsp
The view resolver surrounds the view name with a prefix and a suffix, providing the front controller with the file path to the template.
VIEW TEMPLATE
<!-- IN THE *.jsp FILE -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
<title>Home Page</title>
</head>
<body>
<h1>${hello}</h1>
</body>
</html>
Model data is accessed using the JSP Expression Language.
Thymeleaf
Modern Java Template engine which can process HTML, text, JavaScript or CSS files.
Contrary to JSP, Thymeleaf supports Natural Templating, allowing the template to be correctly displayed in the browser when opened directly, working as a static prototype.
VIEW TEMPLATE WITH Thymeleaf
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<title>Home Page</title>
</head>
<body>
<h1>This is your user:</h1>
<p th:text="${user.name}"></p>
<p th:text="${user.email}"></p>
</body>
</html>
Live codinG
Hello World with Spring Boot MVC
Auto-wiring
Spring auto-wiring enables object dependencies to be injected without the need for explicit configuration.
A Spring-managed bean can be injected into a property by using the @Autowired annotation.
URL templates
An URL template is an URL-like string that contains one or more variable names.
@Controller
public class UserController {
@GetMapping("/users/{id}")
public String getUser(@PathVariable Integer id) {
// (...)
}
}
The @PathVariable annotation can be to bind a method parameter to the value of an URL template variable.
EXERCISE
User Details Pages with Spring Boot MVC
/users → Shows a list of users names
/users/{id} → Shows the details of that particular user
JPA with
Spring Boot
Spring Data
Spring Data is a Spring module whose mission is to provide a consistent programming model for data access.
It makes using data access technologies, and both relational and non-relational databases as easy as pie.
Spring Data JPA is the Spring Data's model responsible for implementing JPA based repositories.
data Access layer
Remember this?
The Data Access layer provides simplified access to data stored in persistent storage.
Data access object Pattern
The DAO pattern allows us to isolate the application/business layer from the persistence layer.
It hides the complexity involved in performing CRUD operations in the underlying storage mechanism from our application.
public interface Dao<T> {
Optional<T> get(Integer id);
List<T> getAll();
void saveOrUpdate(T t);
void delete(T t);
}
DAO EXAMPLE
public class UserDao implements Dao<User> {
(...)
@Override
public Optional<User> get(Integer id) {
return Optional.ofNullable(em.find(User.class, id));
}
@Override
public List<User> getAll() {
return entityManager.createQuery( "SELECT * FROM User user").getResultList();
}
@Override
public void saveOrUpdate(User user) {
(...)
}
@Override
public void delete(User user) {
(...)
}
}
Repository Pattern
The Repository pattern is similar to the DAO pattern in a sense that both deal with data and hide query complexity from the rest of our application.
However, the Repository sits at a higher level, closer to the business logic of an app. The Repository will use a DAO to get the data from the storage and use that data to restore a business object (and vice-versa).
Repository EXAMPLE
Repositories are useful when we're dealing with non-anaemic models. In this case, our user is a fairly complex domain model.
public class UserRepository implements Repository<User> {
private UserDao userDao;
private TweetDao tweetDao;
@Override
public User get(Integer id) {
User user = userDao.read(id);
List<Tweet> tweets = tweetDao.fetchTweets(user.getEmail());
user.setTweets(tweets);
return user;
}
}
Spring repository
The goal of the Spring Data repository abstraction is to reduce the amount of boilerplate code required to implement data access layers.
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
(1)
<S extends T> S save(S entity);
(2)
T findOne(ID primaryKey);
(3)
Iterable<T> findAll();
Long count();
(4)
void delete(T entity);
(5)
boolean exists(ID primaryKey);
(6)
(...)
}
Spring BOOT repository EXAMPLE
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
Customer findById(long id);
}
We don't need to write an implementation of the repository interface. Spring Data JPA creates an implementation when we run the application!
Live coding
Spring Boot JPA
NEXT
Next we will start creating our very own Rent-A-Car Application.
We'll start by creating an API that will allow a web application to consume our Customers and Cars data.
But first, learn what an API truly is.
REST API
with spring boot
@RestController
@ResponseBody - Tells a controller that the object returned is to be automatically serialised into JSON format and sent back into the HttpResponse object.
@RestController - Combines the annotations @Controller and @ResponseBody. Annotating a class with @RestController means that every method of the controller class automatically serialises return objects into an HttpResponse.
@RestController
public class HelloRestController {
@GetMapping("/")
public String hello(){
return "Hello!";
}
}
@RestController With objects
@RequestParam - Used to extract query parameters from the request. Example request:
http://localhost:8080/message?name=Ronald
The application uses the Jackson library to automatically serialise Java instances into JSON.
@RestController
public class HelloRestController {
@GetMapping("/message")
public Message greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return new Message("Hello, " + name);
}
}
JACKSON
Jackson is the standard JSON library for Java. It provides a framework to serialise Java objects to a JSON string, and vice-versa.
Jackson is included automatically, and by default, by the Spring Boot framework.
You can learn more about it here.
POST with @RestController
@RequestBody - Tells a controller that the value of the parameter annotated is to be automatically deserialised into a Java object.
@RestController
public class HelloRestController {
@PostMapping("/newMessage")
public void newMessage(@RequestBody Message message) {
messages.add(message);
}
}
POSTMAN
Postman is a collaboration tool for API development. With Postman, we can send REST, SOAP, and GraphQL requests directly.
Live coding
Postman Overview
Response entity
ResponseEntity - represents an HTTP response, consisting of headers, body, and response code.
@RestController
public class HelloRestController {
@PostMapping("/newMessage")
public ResponseEntity<Message> newMessage(@RequestBody Message message) {
if(message.getText() == null){
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
messages.add(message);
return new ResponseEntity<>(message, HttpStatus.CREATED);
}
}
Live coding
Spring Boot - REST API
Data transfer object
DTO is an object that carries data between processes in order to reduce the number of method calls.
Martin Fowler in Patterns of Enterprise Architecture
In addition, using DTOs to transfer data to/from our application also allows us to separate our presentation logic from the persistence logic.
Data transfer object EXAMple
A DTO is a collection of properties with getters and setters, the represents the data we want to transfer.
public class UserDto {
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
}
Converter
A converter is required to transfer data from DTOs to domain objects and vice-versa.
public class UserConverter {
public static UserDto fromUserEntityToUserDto(User user) {
(...)
}
public static User fromUserDtoToUserEntity(UserDto userDto) {
(...)
}
}
DTO - USage EXAMPLE
@RestController
public class UserRestController {
@PostMapping("/newUser")
public void addUser(@RequestBody UserDto userDto) {
(...)
}
}
javax.validation
JSR 380 is a specification of the Java API for bean validation. It ensures that the properties of a bean meet specific criteria, using annotations such as @NotNull, @Min, and @Max.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
Validation
public class UserDto {
@NotBlank(message = "Must have first name")
private String firstName;
@NotBlank(message = "Must have last name")
private String lastName;
@Email(message = "Email must be valid")
private String email;
@Pattern(regexp = "^\+?[0-9]*$", message = "Phone has invalid characters")
@Size(min=9, max=16)
private String phoneNumber;
}
@Valid
We can validate the deserialised JSON object by adding the @Valid annotation to method parameters.
@RestController
public class UserController {
@PostMapping("/newUser")
public ResponseEntity addUser(@Valid @RequestBody UserDto userDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
(...)
}
}
The BindingResult object contains the results of the evaluation. This object must follow the object to be validated.
The Rent-A-CAr API
overview
We are going to create an application to be used by a car rental company, starting with a REST API that will later be consumed by a JavaScript frontend application.
entities
We will need to store data regarding:
- CLIENTS
- CARS
- RENTALS
Functionality
USERS:
- create users;
- retrieve all users;
- retrieve one user;
- update users;
- delete users;
Functionality
CARS:
- create cars;
- retrieve one car;
- retrieve all cars;
- update cars;
- delete cars;
Functionality
RENTALS:
- create rental;
- retrieve one rental;
- retrieve all rentals;
- delete cars;
- calculate rent price;
- deliver cars;
- return cars;
Exercise
Car Rental - Rest API
AOP
Spring Boot
cross-cutting concerns
Some concerns are implemented across the several layers of our application. Theses concerns are called cross-cutting concerns.
aspect oriented programming
AOP is a programming pattern that increases modularity by allowing the separation of cross-cutting concerns.
With AOP, we define common functionality in one place.
The functionality is applied without modifying the class to which we are applying the new feature.
The cross-cutting concern can now be modularised into special classes, called aspect.
terminology I
JOIN POINT - A point in the application where we apply an AOP aspect
ADVICE - An action that we take either before or after the method execution. Advices are taken for a specific joint point.
POINTCUT - A pointcut is an expression that selects one or more join points where advice is executed
terminology II
WEAVING - The process of applying aspects to a target object, creating a new, proxy object
TARGET - The object in which the aspects are applied
PROXY - The object created after applying the advices to the target object.
aop vs oop
AOP is actually an extension of the Object-Oriented Paradigm.
\ | OOP | AOP |
---|---|---|
Basic Unit | Object (encapsulates methods and attributes) | Aspect (encapsulates pointcuts and advices) |
Entry Point | Pointcut | Method |
Implementation | Advice | Method Body |
Code Construction | Waver | Compiler |
aop advices
There are 5 types of AOP advices:
- BEFORE ADVICE
- AFTER ADVICE
- AROUND ADVICE
- AFTER THROWING
- AFTER RETURNING
LIVE CODING
AOP Example
domain errors
A domain error occurs when a specific input data causes the program to execute a wrong, undesired path.
Example: someone trying to access a user that does not exist in our Rent-A-Car application.
Domain exceptions
Creating dedicated exceptions for signalling business logic errors allows specialised error handling for each situation, but how can we achieve this?
AOP comes to the rescue:
@ControllerAdvice - applies this controller methods to all controllers in the application.
@ExceptionHandler - when the exception is thrown, the method annotated will be called
aop - exception handler
@ControllerAdvice
public class RentacarExceptionHandler {
@ExceptionHandler(value = {
UserNotFoundException.class,
CarNotFoundException.class})
public ResponseEntity<Error> handleNotFoundException(Exception ex, HttpServletRequest request) {
return Error.builder()
.timestamp(new Date())
.message(ex.getMessage())
.method(request.getMethod())
.path(request.getRequestURI())
.build();
}
}
Exercise
Car Rental - Rest API with Exception Handling
security with
Spring Boot
hypertext transfer protocol secure
HTTPS is an internet communication protocol that protects the integrity and confidentiality of data between the user's computer and the site.
Data sent using HTTPS is secured via Transport Layer Security protocol (TLS), providing three key layers of protection:
- Encryption
- Data Integrity
- Authentication
We can enable HTTPS in our application using Spring Boot. Here's how.
Application security
The process of developing, adding, and testing security features (hardware and software) within applications to prevent security vulnerabilities against threats such as unauthorised access and/or data modification.
Types of application security
- AUTHENTICATION - Procedures that ensure the identity of a user. Multi-factor authentication requires more than one step.
- AUTHORISATION - Comparison of the user’s identity with a list of authorised users, in order to verify if they have the necessary permissions to access a given feature.
- ENCRYPTION - In cloud-based applications, where traffic containing sensitive data travels between the end user and the cloud, that traffic can be encrypted to keep the data safe.
- LOGGING - Application log files provide a time-stamped record of which aspects of the application were accessed and by whom.
spring security
Spring Security is the standard framework for securing Spring-based applications.
It is a powerful, highly customisable authentication and access-control framework.
basic authentication
HTTP Basic Authentication requires that the server request a username and password from the web client and verify that they are valid by comparing them against a database of authorised users.
HTTP basic authentication sends user names and passwords over the Internet as text, so it's not a secure authentication mechanism.
Password encryption with bcrypt
bcrypt is one of the most famous password-hashing functions.
SALT - Generating random bytes (the salt) and combining it with the password before hashing creates unique hashes across each user’s password. bcrypt allows us to choose the value of salt rounds.
Live Coding
Basic Authentication
STATE vs http
HTTP is a stateless protocol.
We need a way to store user data between requests, in order to associate a request to any other request.
Cookies
A web cookie is a packet of data that a computer receives and then sends back without changing or altering it.
A cookie is created by a server and sent to the browser when we visit a website.
Cookie Types
- Session cookies - temporary cookies that memorize our online activities. Useful when we're online shopping.
-
Persistent cookies - work by tracking our online preferences. This is how browsers remember and store our login information, language selections, menu preferences, etc.
- Tracking cookies - collect data based on our online behaviour. These are used to select the ads that appear on websites we visit and display content relevant to our interests.
Cookie-based authentication
A Cookie-based authentication uses HTTP cookies to authenticate the client requests and maintain session information on the server over the stateless HTTP protocol.
Cookie-based authentication has been the default, tried-and-true method for handling user authentication for a long time.
LIVE codinG
Cookie Implementation
LIVE codinG
Cookie Implementation
authorisation roles
A role is a group of permissions.
Roles can be assigned to a single user or user group.
A user or user group can have multiple roles.
the user
public class UserEntity extends AbstractEntity {
(...)
@Column(nullable = false)
private String encryptedPassword;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private UserRole role;
}
the role
public enum UserRole {
CUSTOMER,
EMPLOYEE,
ADMIN
}
@PreAuthorize
@GetMapping("/{userId}")
@PreAuthorize("@authorized.isUser(#userId) ||" +
"@authorized.hasRole(\"EMPLOYEE\") ||" +
"@authorized.hasRole(\"ADMIN\")")
public ResponseEntity<UserDetailsDto> getUserById(@PathVariable long userId) {
(...)
}
Exercise
Car Rental - Rest API with Security
Spring-Boot
By Soraia Veríssimo
Spring-Boot
- 1,942