AdvanceJava Day
AdvanceJava Day
md 7/12/2021
Java EE Module
Contents
Servlet
JSP
Spring
Spring Boot
Hibernate
JPA
Spring Data JPA
Pre-requisites
Java
JDBC (DAO approach)
Collections (ArrayList and HashMap)
Reflection, Annotations, Proxy -- To understand internals
https://dzone.com/articles/java-dynamic-proxy
OOP (Class, Object, Inheritance, Overriding, etc).
Stream programming (map(), filter(), etc.) -- Optional
Web Programming
HTML -- html forms
React
Schedule
3 Weeks
Week 1:
Foundations: Servlets & JSP
Week 2 + 3:
Spring & Hibernate
Week 3 (End):
Exam oriented topics
Lectures:
9:00 am to 1:30 pm -- Lecture
1/4
day01.md 7/12/2021
30 mins break
3:00 pm to 7:00 pm -- Lab
Evaluation
Software Setup
Apache Tomcat 9.x
Spring Tool Suite (Eclipse)
Java EE Introduction
Java SE - Standard Edition
Java platform
Applications: Console, Desktop (AWT, Swing, JavaFX, ...)
Java EE - Java Enterprise Edition
Enterprise -- Business, Organization, ...
SBI Bank
LIC
Indian Rail
Amazon
Netflix
Java EE versions
Java EE 1.2 -- 1999
Java EE 1.3 -- 2001
Java EE 1.4 -- 2003
Java EE 5 -- 2006
Java EE 6 -- 2009
Java EE 7 -- 2013
** Java EE 8 -- 2017 -- Last release of Java EE (by Oracle)
Jakarta EE 8 -- 2018 -- First release of Jakarta EE (by Eclipse)
Due to copyright issues Java EE is renamed to Jakarta EE.
https://javaee.github.io/javaee-spec/javadocs/
HTTP Protocol
Web Server: Program/Application that enable deploying/executing one/more web applications in it.
e.g. IIS (Microsoft), Apache Web Server (PHP), NGINX (PHP).
Java Web Server: Java (JVM based) application that enable deploying one/more Java web
applications in it.
e.g. Tomcat, Lotus, JBoss, WebSphere, etc.
Web Clients: These web applications will be consumed by the clients over HTTP protocol.
2/4
day01.md 7/12/2021
Java Server
Java (JVM based) application that enable deploying one/more Java web applications in it.
Java Web Server implements Java EE (suite of) specifications.
e.g. javax.servlet.Servlet interface (spec) implemented into the classes
javax.servlet.http.HttpServlet (class implemented in web server)
javax.servlet.ftp.FtpServlet (class implemented in web server)
Two types of Java servers
Java Web Server
Java Application Server
Apache Tomcat
Java Web Server
Directory structure
bin: Contains tomcat binaries and scripts (e.g. tomcat9.exe, startup.bat, shutdown.bat, etc.)
conf: Contains tomcat config files (e.g. server.xml, users.xml, etc.)
server.xml for tomcat port setting (Check port number for tomcat downloaded on your
computer)
lib: Contains tomcat spec implementation jars (e.g. servlet-api.jar, jsp-api.jar, etc.)
3/4
day01.md 7/12/2021
4/4
day02.md 7/13/2021
HTTP protocol
GET request is generated in following places
Submit HTML form with method="GET"
When user enter an URL in browser
When user click on a Hyperlink <a href="...">
POST request is generated in following places
Submit HTML form with method="POST"
Apache Tomcat
Download Tomcat zip/rar.
Extract Tomcat.
Set Environment variable: JAVA_HOME
This PC --> Properties --> Advanced System Settings --> Advanced --> Environment Variables
New (User or System variable)
JAVA_HOME = "C:\Program Files\AdoptOpenJDK\jdk-11.0.9.101-hotspot"
PATH add "C:\Program Files\AdoptOpenJDK\jdk-11.0.9.101-hotspot\bin"
Run tomcat/bin/startup.bat.
Browser: http://localhost:8080/
Stop tomcat/bin/shutdown.bat.
index.html
WEB-INF
web.xml
lib
classes
Start the tomcat (bin/startup.bat)
Browser: http://localhost:8080/helloweb/index.html
index.html is visible on browser
Browser: http://localhost:8080/helloweb/WEB-INF/web.xml
404 - Not found
All files under WEB-INF are private to the application and not accessible to end user "directly".
.jar --> Java archive (Zip format)
.war --> Web archive (Zip format)
Java EE web application directory structure
To deploy any Java EE web application it must be packaged as .war file and deploy in tomcat/webapps.
Java Servlets
Servlet is user-defined java class inherited from javax.servlet.Servlet interface.
javax.servlet.Servlet interface
init():
Called only once by web container when first request is made for the servlet.
For the first request to the servlet
Servlet class (.class file) is loaded
Object is created (by web container)
Constructor is executed (by JVM)
init() is called (by web container) -- can access web server facilities like connection
pool, JNDI, ...
Programmer override this method to perform one-time initialization e.g. getting init
params, create one-time database connection, etc.
Receives a param -- ServletConfig
ServletConfig object is created by web container
Stores information about current servlet
If initialization fails, must throw ServletException (if exception is of other type, it should be
nested/chained in ServletException).
Then web container will not process the servlet further.
destroy():
Called only once by web container when server shutdown.
While server shutdown:
Call destroy() method of all servlet objects
Objects are ready for garbage collection.
Programmer override this method to perform de-initialization. Typically resources acquired
during init() are released in destroy().
destroy() method should not fail. Handle exception if any.
service():
2/5
day02.md 7/13/2021
init() implementation
destroy() implementation
service() implementation -- to handle HTTP request
else if(method.equals("PUT"))
this.doPut(req, resp); // ...
else if(method.equals("DELETE"))
this.doDelete(req, resp); // ...
else if(method.equals("HEAD"))
this.doHead(req, resp);
else if(method.equals("TRACE"))
this.doTrace(req, resp);
else if(method.equals("OPTIONS"))
this.doOptions(req, resp);
// ...
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
... {
throw new RuntimeException(...);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
... {
throw new RuntimeException(...);
}
// ...
}
package sunbeam;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import javax.servlet.annotation.*;
@WebServlet("/hello") // url-pattern
public class MyServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("MyServlet.init() called.");
}
@Override
public void destroy() {
System.out.println("MyServlet.destroy() called.");
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
System.out.println("MyServlet.doGet() called.");
processRequest(req, resp);
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
4/5
day02.md 7/13/2021
System.out.println("MyServlet.doPost() called.");
processRequest(req, resp);
}
public void processRequest(HttpServletRequest req, HttpServletResponse
resp) throws IOException, ServletException {
// business logic
// presentation logic
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Java EE</title>");
out.println("</head>");
out.println("<body>");
out.println("<h2>Hello Servlet</h2>");
out.println("<h5>Response generated at: " + new Date() + "</h5>");
out.println("</body>");
out.println("</html>");
}
}
cmd> cd tomcat\webapps\helloweb\WEB-INF\src
cmd> set CLASSPATH=tomcat\lib\servlet-api.jar;%CLASSPATH%
cmd> javac -d ..\classes MyServlet.java
Start tomcat.
Browser: http://localhost:8080/helloweb/hello
5/5
day03.md 7/14/2021
Java EE
Agenda
Servlet init-param
Servlet load-on-startup
Inter-servlet communication/navigation
State management
Servlet Configuration
load-on-startup
By default servlet class is loaded and instantiated, when first request is arrived for the servlet.
Using <load-on-startup> under <servlet> tag, servlet can be loaded and instantiated as soon as
application is deployed.
e.g. <load-on-startup>1</load-on-startup>
A positive number given in body of tag, indicate sequence of servlet loading, if there are multiple
servlets with load-on-startup tag.
If this number is negative, servlet is loaded lazily (upon first request).
Alternatively it can also be configured in @WebServlet(initParams = { ... }).
init-param
Some configurable information can be associated with servlet using init-param under <servlet> tag in
web.xml.
Example:
<init-param>
<param-name>DB_URL</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
This value can be accessed in servlet class using ServletConfig object as:
1/4
day03.md 7/14/2021
// in init() method
String dbUrl = config.getInitParameter("DB_URL");
// ...
Since GenericServlet class is inherited from ServletConfig, it can also be accessed using servlet object
"this".
Inter-servlet communication/navigation
Redirection
Can redirect from any page to any other page of the same application or different application.
resp.sendRedirect(url);
When sendRedirect() is called, a temp response (status code 302 and destination url) is sent to the
browser; due to which browser make a new request to the new link.
In this case two requests are originated from the browser and hence browser is aware of the navigation.
This is slower process.
RequestDispatcher
Only one request is originated from the client, and single response is given back.
RequestDispatcher rd = req.getRequestDispatcher("url");
// ...
RequestDispatcher rd = ctx.getRequestDispatcher("/url");
rd.forward(req, resp);
// OR
rd.include(req, resp);
Navigation can be done only to the pages within the same application.
2/4
day03.md 7/14/2021
Forwarding
Request is forwarded to next servlet from which response will be given to the client.
Including:
Request is given to next servlet, which performs some processing and return back to the calling servlet.
The response generated by the second servlet will be included into first servlet's response.
State Management
State Management Classfication
Cookie
To store info about the client, server send that info in textual key-value form to the client known as
"cookie".
Once cookie is received by the client, thereafter with each request cookie is sent back to the server.
Cookie can store only text data upto 4KB.
Cookies Types:
Temporary Cookie:
Cookie is stored in browser memory and will be destroyed when browser is closed.
Persistent Cookie:
Cookie is stored in client machine (disk) as text file and will be persisted even if browser is
closed.
To create and send cookie
3/4
day03.md 7/14/2021
Cookie methods
Refer java docs
4/4
day04.md 7/15/2021
Java EE
Agenda
Error: tomcat v9.0 server at localhost failed to start
State Management
Session
Session Tracking
Query String
Hidden form fields
Application (ServletContext)
Filters
Error handling
tomcat v9.0 server at localhost failed to start
importing of Servlet packages
Cookie
Max age:
+ve value = number of seconds cookie should be persisted on client system.
-ve value = (-1) cookie is temporary (auto deleted when cookie when browser is closed).
0 = cookie is deleted.
Session
For each client one session object is created on the server side, in which client specific state/info can be
saved.
Session object is like a map, where data is stored in key/value pairs.
The key must be a string, while value can be any object.
HttpSession methods
void setAttribute(String key, Object value);
1/3
day04.md 7/15/2021
<session-config>
<session-timeout>10</session-timeout>
</session-config>
Session Tracking
Each session is identified using a unique session id, which is associated with the client.
There are two ways of this association (tracking):
cookie based
url rewriting
Cookie based
By default, when new session is created (req.getSession() is called first time) a cookie is created and
sessionid is sent to client via that cookie.
For suqsequent calls to req.getSession() access the appropriate session object by getting sessionid from
that cookie.
Url rewriting
ServletContext
For each web application, web container creates a singleton object called as "ServletContext" during
application deployment.
To store the data globally so that it can be accessed for all request to all pages (servlets) by all
users.
To navigate from one page (servlet) to another using RequestDispatcher. (refer notes of
RequestDispatcher)
To access application config params (context params).
req.getServletContext()
2/3
day04.md 7/15/2021
session.getServletContext()
config.getServletContext()
this.getServletContext() // In Servlet class
Context Parameters
ServletConfig can be used to get init param for specific servlet (from web.xml).
In web.xml we can declare the values which can be accessible in entire application in form of
context params:
<web-app>
// ...
<context-param>
<param-name>color</param-name>
<param-value>yellow</param-value>
</context-param>
// ...
</web-app>
This param can be accessed into the web application via ServletContext object as:
3/3
day05.md 7/16/2021
Java EE
Agenda
Listeners
Filters
JSP
JSP Life cycle
JSP directives
JSP implicit objects
JSP standard actions
Listeners
These interfaces are used to handle events in the web application e.g. application start (context
initialization), application stop (context uninit), session start, session end, new value added into session,
any value removed from session, etc.
interface ServletContextListener
interface HttpSessionListener
interface HttpSessionAttributeListener:
interface HttpSessionActivationListener:
Refer docs.
interface HttpSessionBindingListener:
Refer docs.
interface ServletContextAttributeListener:
Refer docs.
interface ServletRequestListener:
Refer docs.
interface ServletRequestAttributeListener:
1/5
day05.md 7/16/2021
Refer docs.
Filters
Filter is way of AOP in Java EE application.
Can perform pre-processing and/or post-processing while accessing any servlet/jsp.
Multiple filters can be executed in a chain.
Filter life cycle (is similar to Servlet life cycle).
init(): Object is created when application is deployed and init() is called for one-time initialization.
destroy(): Executed when server shut-down for one-time de-initialization.
doFilter(): Pre-processing, invoke next component in chain and post-processing.
Configured using @WebFilter annotation (refer docs) or in web.xml
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>sunbeam.filters.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Typically URL pattern is corresponds to some servlet. When servlet is requested, the filter doFilter() is
invoked.
URL may include wild-card /* indicating all the servlets.
JSP
JSP is outdated.
Simplest JSP page = HTML page.
JSP is internally converted into servlets while execution.
JSP syntax
used to declare fields and methods which will not be executed per request. e.g. jspInit(),
jspDestroy(), other methods, all fields, etc.
can write one or more declaration blocks
the java expressions whose result (string) will be directly embedded into generated html.
Executed for each request.
will become part of _jspService() method during translation phase.
JSP Example
3/5
day05.md 7/16/2021
<%
out.println(new Date().toString());
%>
<br/>
<%= new Date().toString() %>
</body>
</html>
Assignments
Maintain count of online users. Add a page for admin login to see number of online users.
Complete the Bookshop assignment with SecurityFilter.
Modify SecurityFilter to ensure that Admin pages are not accessible to the customers.
Execute hello jsp using Eclipse. (Create it under webapp directory).
5/5
day06.md 7/17/2021
Java EE
Agenda
JSP directives
Custom Error Pages
JSP Implicit objects
JSP standard actions
Java beans
JSP Expression language
JSTL
JSP Custom tags
MVC
JSP directives
https://www.tutorialspoint.com/jsp/jsp_directives.htm
<%@ page ... %>
language="java" --> server side code (scriptlet, declaration & expression language = java)
contentType="text/html"
session="true" --> automatically session is created for this page -- internally calls
request.getSession() in generated servlet.
info="Description of the JSP page" --> kind of documentation
extends="javax.servlet.http.HttpServlet" --> generated servlet class must be inherited from this
class.
isErrorPage="false" --> defines whether this page is designed to display error messages.
false --> simple JSP page (not an error page)
true --> an error page (can access "exception" object to display error).
errorPage="" --> name of error to be displayed when error is generated in current page.
isELIgnored="false"
false --> process JSP EL.
true --> ignore JSP EL syntax ${...}
<%@ include file="..." %>
Includes another file (jsp, html, ...) into current jsp.
As per standard, this is static inclusion (done at translation stage).
However web server implementors may follow dynamic inclusion (RequestDispatcher.include()).
Commonly used for consistent look & feel (common header & footer).
<%@ taglib ... %>
Use custom tags/third party tags into JSP pages.
Tags = Business logic + Presentation logic
The error pages can be configured in web.xml, so that for specific error specific pages can be displayed.
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/forbidden.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
If error page is configured in web.xml as well as page directive, then page directive is get precedance.
1. request: HttpServletRequest
2. response: HttpServletResponse
3. config: ServletConfig
4. application: ServletContext
5. session: HttpSession
6. out: JspWriter
7. page: Object -> this pointer
8. pageContext: PageContext -> to save some data on page scope (accessible on that page for that
request only)
9. exception: Throwable -> accessible only in error pages
These tags are used to embed applets (and other plugins like flash) into jsp pages.
2/5
day06.md 7/17/2021
Inter-servlet communication
<jsp:forward page="pageurl"/>
<%-- OR --%>
<jsp:include page="pageurl"/>
RequestDispatched rd = req.getRequestDispatcher("pageurl");
rd.forward(req, resp);
// OR
rd.include(req, resp);
<jsp:forward page="page2.jsp">
<jsp:param name="key1" value="value1"/>
</jsp:forward>
// in page2.jsp
String val = request.getParameter("key1");
3/5
day06.md 7/17/2021
jsp:useBean
jsp:useBean is used to access the bean object from the given scope if available; otherwise
create a new object and add in the given scope.
This tag check the whether any object is present in the given scope with given name
(id).
If object is present, it will be accessed by that name.
If object is not present, class will be loaded and object will be created at runtime.
Then object will added into given scope with given name.
Example
Internals
// pseudo code
UpperCaseBean1 ub = (UpperCaseBean1)
pageContext.getAttribute("ub");
if(ub == null) {
ub = new UpperCaseBean1(); // object is created using
reflection
pageContext.setAttribute("ub", ub);
}
Scopes
jsp:setProperty
Example
4/5
day06.md 7/17/2021
Internally find corresponding setter method (i.e. setPropName()) and execute it on given
object.
"value" is used to give fix value, while "param" is used to give value from request
parameter.
If property="*", all properties having name same as request params will be automatically
initialized.
jsp:getProperty
Example
Internally find corresponding getter method (i.e. getPropName()) and execute it. The
return value will be added into html response.
Before calling jsp:setProperty or jsp:getProperty the jsp page must have jsp:useBean tag.
5/5
day07.md 7/20/2021
Java EE
Agenda
MVC pattern
JNDI
Maven
Spring Introduction
MVC Pattern
Model I architecture
Model II architecture
JNDI
https://docs.oracle.com/javase/tutorial/jndi/overview/index.html
Maven
Maven is a powerful build tool for Java software projects.
Build tool
A build tool is a tool that automates everything related to building the software project. Building a
software project typically includes one or more of these activities:
Generating source code (if auto-generated code is used in the project).
Generating documentation from the source code.
Compiling source code.
Packaging compiled code into JAR files or ZIP files.
Installing the packaged code on a server, in a repository or somewhere else.
The advantage of automating the build process is that you minimize the risk of humans making errors
while building the software manually.
Additionally, an automated build tool is typically faster than a human performing the same steps
manually.
1/3
day07.md 7/20/2021
Maven is centered around the concept of POM files (Project Object Model).
A POM file is an XML representation of project resources like source code, test code, dependencies
(external JARs used) etc.
The POM file should be located in the root directory of the project it belongs to.
Maven working
1. Reads pom.xml
2. Download dependencies into local repository
3. Executes life cycles, build phases and goals.
4. Execute plugins.
POM file
The groupId element is a unique ID for an organization, or a project (an open source project, for
instance). Most often you will use a group ID which is similar to the root Java package name of the
project.
The artifactId element contains the name of the project you are building.
The versionId element contains the version number of the project. SNAPSHOP versions indicate that
project is in active development (not production ready).
Dependencies
The build process in Maven is split up into build life cycles, phases and goals.
A build life cycle consists of a sequence of build phases, and each build phase consists of a sequence of
goals.
When you run Maven you pass a command to Maven.
This command is the name of a build life cycle, phase or goal.
If a life cycle is requested executed, all build phases in that life cycle are executed.
If a build phase is requested executed, all build phases before it in the pre-defined sequence of build
phases are executed too.
2/3
day07.md 7/20/2021
validate: Validates that the project is correct and all necessary information is available. This also makes
sure the dependencies are downloaded.
compile: Compiles the source code of the project.
test: Runs the tests against the compiled source code using a suitable unit testing framework. These
tests should not require the code be packaged or deployed.
package: Packs the compiled code in its distributable format, such as a JAR.
install: Install the package into the local repository, for use as a dependency in other projects locally.
deploy: Copies the final package to the remote repository for sharing with other developers and
projects.
3/3
day10.md 11/24/2021
Java EE
Agenda
Spring Concepts
Why Spring
Features
Advantages
Limitations
Spring Boot
Why Spring Boot
Features
Advantages
Dependecy Injection
Spring Config
XML Based Config
Annotation Based Config
Mixed Config
Spring Boot "Hello World"
Auto-wiring
Spring IO platform
Spring XD (https://docs.spring.io/spring-xd/docs/current/reference/html/)
Spring cloud (https://spring.io/projects/spring-cloud-netflix)
Spring boot (https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/)
Spring framework (https://docs.spring.io/spring-framework/docs/4.3.29.RELEASE/spring-framework-
reference/htmlsingle/)
Spring Documentation (https://docs.spring.io/spring-framework/docs/5.3.8/javadoc-api/)
Why Spring
Spring bean is a java POJO class with one or more business logic methods.
Spring beans are created and managed by Spring container.
Inversion of Control - Dependency injection.
OOP -- Object Oriented Programming -- Composition
Outer object --> Inner object(s)
Car <>-- Engine
Car <>-- Wheels
Spring automates object creation as well as initialization.
Inversion-of-Control
OOP (Bottom-up) vs POP (Top-down)
Manual Object Initialization vs DI Object Initialization (Inverted)
Test driven approach: Easy testing support.
Unit testing/Mocking support in out-of-box.
Beans can be tested independently.
Extensive but modular and flexible.
Extensive: Huge -- so many modules, sub-projects, wide spectrum
Modular: Separate sub-projects/modules are available
Flexible: Can use only modules you need on top of Spring core
Smooth integration with existing technologies like JDBC, JNDI, ORM, Mailing, etc.
Eliminate boiler-plate code - ORM, JDBC, Security, etc.
JDBC
Load & register class (managed by spring)
Create connection (managed by spring)
Create statement (managed by spring)
Execute the query (managed by spring)
Process the result (ResultSet) -- supply SQL statement, parameters and process result.
Close all (managed by spring)
Hibernate
Hibernate configuration (.cfg.xml or coding) (managed by spring)
Create SessionFactory (managed by spring)
Create session (managed by spring)
transaction management (managed by spring)
CRUD operations or Query execution -- user-defined
Cleanup (managed by spring)
Unified transaction management (local & distributed/global) -- @Transactional
Local transactions: Within same database
Global transactions - JTA: Across the databases
Easier J2EE development through Spring Web MVC (Pull) and Web sockets (Push).
Consistent and "readable" unchecked exceptions - wraps technology-specific exceptions.
Core feature
Dependency injection
Spring IoC container - Bean life-cycle management
Container -- Life-cycle
JRE container in browser: Applet life-cycle
Servlet/JSP container in web-server: Servlet/JSP life-cycle
2/6
day10.md 11/24/2021
step 1: Create new Maven project. Fill project details like groupId, artifactId, packaging=jar, etc. Add
spring-context dependency (5.3.13) in POM.xml.
step 2: Create bean class BoxImpl with appropriate fields and methods (as discussed in the class).
step 3: In resources folder, create "Spring Bean Configuration File" (beans.xml) and configure beans b1
(setter based di) & b2 (constructor based di) -- (as discussed in class).
step 4: Create a Main class and create ClassPathXmlApplicationContext, create beans and invoke
business logic (as discussed in class).
step 1: Create new Maven project. Fill project details like groupId, artifactId, packaging=jar, etc. Add
spring-context dependency (5.3.13) in POM.xml.
step 2: Create bean class BoxImpl with appropriate fields and methods (as discussed in the class).
step 3: Create AppConfig class annotated with @Configuration and create beans b1 & b2 in it (as
discussed in class).
step 4: Create a Main class and create AnnotationConfigurationXmlApplicationContext, create beans
and invoke business logic (as discussed in class).
Spring hurdles
Heavy configuration
XML configuration
Java (annotation) configuration
Mixed configuration
Module versioning/compatibility
Spring & Spring-Security version
Hibernate & Cache version
...
Application deployment
Web-server deployment
Containerisation - Docker
Complex Microservice development
Spring Boot
Spring Boot is a Framework from "The Spring Team" to ease the bootstrapping and development of
new Spring Applications.
Framework
Ease bootstrapping - Quick Start (Rapid Application Development)
New applications - Not good choice for legacy applications
Abstraction/integration/simplification over existing spring framework/modules.
Spring core
Spring Web MVC
Spring Security
3/6
day10.md 11/24/2021
Spring ORM
...
NOT replacement or performance improvement of Spring framework.
Not replacement, but it is abstraction.
Underlying same Spring framework is working -- with same speed.
Spring Boot = Spring framework + Embedded web-server + Auto-configuration - XML configuration -
Jar conflicts
JSON -- Jackson
Test -- JUnit
You can change the configuration/technologies by adding alternates on pom.xml (classpath).
Provide lot of non-functional common features (e.g. security, servers, health checks, ...).
Easy deployment and Containerisation.
Embedded Web Server for web applications.
step 1: New "Spring Boot Starter project". Fill project groupId, artifactId, name, etc details.
step 2: Inherit main class from CommandLineRunner interface and implement run() method.
step 3: Create bean class BoxImpl with appropriate fields and methods (as discussed in the class).
step 4: Create AppConfig class annotated with @Configuration and create beans b1 & b2 in it (as
discussed in class).
step 5: @Autowired ApplicationContext ctx; into main class.
step 6: In main class run() method, create beans and invoke business logic (as discussed in class).
@SpringBootApplication annotation
SpringApplication class
5/6
day10.md 11/24/2021
Console application.
By default take bean config from @Configuration classes.
Demo 04
Lab Assignment
interface Person
class PersonImpl implements Person
fields: name, age, email
Add Person dependency into AccountImpl class i.e. Person accHolder and provide getter/setter for the
same. Also add getter/setter for accHolder into Account interface. Modify AccountImpl.toString() to
display accHolder details as well.
In AppConfig class create two person beans "p1" and "p2" using Setter Based DI and Constructor Based
DI respectively.
In main class run() method, access them using ctx.getBean(). Use acc.setAccHolder() to the set some
person bean into acc object. Invoke toString() to test if it is set correctly.
6/6
day11.md 11/25/2021
Java EE
Agenda
Stereo-Type Annotations
Spring Auto-wiring
Spring SpEL
Spring Bean life-cycle
ApplicationContext vs BeanFactory
Spring Bean scopes
ConfigurationProperties
Demo 05 (ConfigurationProperties)
Auto-wiring
Demo 05 (Auto-wiring)
Test 1
1/4
day11.md 11/25/2021
Test 2
Test 3
Test 4
Test 5
Test 6
Test 7
SpEL
https://docs.spring.io/spring-framework/docs/3.0.x/reference/expressions.html
Demo 06 (@Value)
step 7: Create BoxInfo class with fields like length, breadth, height, volume, surfaceArea, perimeter and
box.
step 8: Use @Value to initialize all these members.
step 9: Create @Bean "boxInfo" in AppConfig class.
step 10: In main() test BoxInfo class.
@Autowired Assignment
3/4
day11.md 11/25/2021
4/4
day12.md 11/26/2021
Java EE
Agenda
ApplicationContext vs BeanFactory
Spring Bean scopes
Spring Boot JDBC Integration
Spring Boot Web MVC
ApplicationContext vs BeanFactory
step 1: Implement Box interface and BoxImpl class. In BoxImpl, also implement BeanNameAware
interface.
step 2: In AppConfig create @Bean b1 as Singleton and @Bean b2 as Prototype.
step 3: In main() try creating objects of the beans.
Note that:
"b1" bean is created at the start of application. The multiple getBean("b1") returns same
reference.
"b2" bean is created each time getBean() is called. Obviously returns different reference for each
call.
Optional Assignment
step 4: Implement Inner1 as Prototype bean and Outer1 as Singleton bean. Autowire Inner1 bean inside
Outer1.
step 5: Create Outer1 bean in main() and try calling getInner() multiple times.
Note that:
Both Outer1 & Inner1 beans are created at the start of appplication. Inner1 is created to
Autowire in Outer1.
Multiple calls to getInner() returns same Inner1 bean reference.
1/5
day12.md 11/26/2021
step 1: Create new Spring Starter project. Add Starter dependencies for MySQL and JDBC API. Also in
application.properties, add datasource Configuration.
spring.datasource.url=jdbc:mysql://localhost:3306/advjava
spring.datasource.username=nilesh
spring.datasource.password=nilesh
step 2: Create required POJO classes i.e. User, Topic and Tutorial.
step 3: Create UserRowMapper class inherited from RowMapper interface. Its mapRow() method should
get data from resultSet and return User object.
step 4: Create UserDaoImpl class and mark it as @Repository. Declare jdbcTemplate as its field and
provide parameterized constructor for auto-wiring. Using @Autowired on constructor is optional.
step 5: Implement method User findByEmail(String email) in UserDaoImpl.
step 6: Create UserServiceImpl class and mark it as @Service. Declare userDao as its field and provide
parameterized constructor for auto-wiring. Using @Autowired on constructor is optional.
step 7: Implement method User findUserByEmail(String email) in UserServiceImpl, which in turn call
userDao.findByEmail().
step 8: Implement method User authenticateUser(String email, String password) in UserServiceImpl,
which in turn call userDao.findByEmail() and validate password.
step 9: Inherit main class from CommandLineRunner and implement its run() method.
step 10: In main class @Autowired userService and test its methods one by one.
step 11: Create TopicRowMapper class inherited from RowMapper interface. Its mapRow() method
should get data from resultSet and return Topic object.
step 12: Create TopicDaoImpl class and mark it as @Repository. Declare jdbcTemplate as its field and
provide parameterized constructor for auto-wiring. Using @Autowired on constructor is optional.
step 13: Implement method List<Topic> findAll() in topicDaoImpl.
step 13: Create TutorialServiceImpl class and mark it as @Service. @Autowired topicDao field in it
(field-based DI).
step 14: Implement method findAllTopics() in TutorialServiceImpl, which in turn call topicDao.findAll().
step 15: Create TutorialRowMapper class inherited from RowMapper interface. Its mapRow() method
should get data from resultSet and return Topic object. Mark class as @Component.
step 16: Create TutorialDaoImpl class and mark it as @Repository. Declare jdbcTemplate and
tutorialRowMapper as its fields and provide parameterized constructor for auto-wiring. Use
2/5
day12.md 11/26/2021
https://youtube.com/playlist?list=PL74Vj_mzs_d1OKBSVK38zn6cLdOvAfnDt
MVC Concepts
MVC is design-pattern.
Divide application code into multiple relevant components to make application maintainable and
extendable.
M: Model: Data of the application.
V: View: Appearance of data.
C: Controller: Interaction between business logic & views and Navigation.
Custom MVC implementation using servlets and jsp:
Model: Java beans
View: JSP pages
Controller: ControllerServlet (typically -- load-on-startup=1, config)
Spring MVC components
Model: POJO classes holding data between view & controller.
View: "JSP" or Thymeleaf or Freemarker pages
Controller: Spring Front Controller i.e. DispatcherServlet
User defined controller: Interact with front controller to collect/send data to appropriate view,
process with service layer.
3/5
day12.md 11/26/2021
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
@Controller
public class WelcomeController {
@RequestMapping("/welcome") // like servlet url-pattern
public String home(Model model) {
model.addAttribute("curDate", new Date());
return "index"; // view name = index --> /WEB-
INF/jsp/index.jsp
}
}
</head>
<body>
<h1>Welcome to Spring MVC</h1>
<h3>Sunbeam Infotech</h3>
<p>
${curDate}
</p>
</body>
</html>
5/5
day13.md 11/27/2021
Java EE
Agenda
Spring Web MVC
Request handler methods
using HTML tags
using Spring tags
State Management
Flexible signatures
https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html (17.3.3)
OR
1/9
day13.md 11/27/2021
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
spring.datasource.url=jdbc:mysql://localhost:3306/advjava
spring.datasource.username=nilesh
spring.datasource.password=nilesh
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Copy POJOs (User, Topic, and Tutorial), DAOs (UserDaoImpl, TopicDaoImpl, TutorialDaoImpl and
respective RowMappers), Services (UserServiceImpl and TutorialServiceImpl) from the Demo 08.
Create com.sunbeam.controllers.UserControllerImpl class with following method
@RequestMapping("/login") // url-pattern
public String login() {
return "login"; // view-name: /WEB-INF/jsp/login.jsp
}
2/9
day13.md 11/27/2021
Create webapp/WEB-INF/jsp/login.jsp.
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Login</title>
</head>
<body>
<h2>Online Tutorials</h2>
<form method="post" action="validate">
<table>
<tr>
<td>Email:</td>
<td><input type="text" name="email"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Sign In"/>
<a href="#">Sign Up</a>
</td>
</tr>
</table>
</form>
</body>
</html>
Run application (Stop previously spring mvc running application or tomcat, if any).
Browser: http://localhost:8080/login
Create model/pojo class com.sunbeam.pojos.Credentials to collect email and password from login.jsp.
In UserControllerImpl class @Autowired userService (field based or constructor based autowiring).
In UserControllerImpl class add validate() method. Note that login.jsp form action="validate" is mapped
to @RequestMapping("/validate"). Also method return to "failed" JSP page if login is invalid; otherwise
will be redirected to the URL manage or topics (Not implemented yet, so will get 404 now).
@RequestMapping("/validate")
public String validate(Credential cred) {
User user = loginService.authenticateUser(cred.getEmail(),
cred.getPassword());
if(user == null)
return "failed";
if(user.getRole().equals("admin"))
return "manage";
return "topics";
}
3/9
day13.md 11/27/2021
Copy mvctutorial1 as new project mvctutorial2. Rename name & artifactId into pom.xml and update the
Maven project.
@RequestMapping("/login")
public String login(Model model) {
Credentials cred = new Credentials("guest@gmail.com", "");
model.addAttribute("command", cred);
return "login";
}
4/9
day13.md 11/27/2021
@RequestMapping("/validate")
public String validate(Credential cred) {
User user = loginService.authenticateUser(cred.getEmail(),
cred.getPassword());
if(user == null)
return "failed";
if(user.getRole().equals("admin"))
return "redirect:manage";
return "redirect:topics";
}
Browser: http://localhost:8080/login
Create a POJO class for TopicSelection. It has single member int "topic".
@RequestMapping("/topics")
public String topics(Model model) {
List<Topic> list = tutorialService.getTopics();
model.addAttribute("topicList", list);
int topicId = 0;
if(!list.isEmpty())
topicId = list.get(0).getId();
model.addAttribute("command", new TopicSelection(topicId));
return "topics";
}
5/9
day13.md 11/27/2021
@RequestMapping("/topictutorials")
public String topicTutorials(@RequestParam("topic") int topicId, Model
model) {
List<Tutorial> tutorialList =
tutorialService.findTopicTutorials(topicId);
model.addAttribute("tutorialList", tutorialList);
return "topictutorials"; // --> topictutorials.jsp
}
Create webapp/WEB-INF/jsp/topictutorials.jsp.
6/9
day13.md 11/27/2021
</body>
</html>
@RequestMapping("/details")
public String details(@RequestParam("id") int tutorialId, Model model) {
Tutorial tutorial = tutorialService.findTutorialById(tutorialId);
model.addAttribute("tutorial", tutorial);
return "details"; // --> details.jsp
}
Create webapp/WEB-INF/jsp/details.jsp.
<h2>Tutorial</h2>
<h4>${tutorial.name}</h4>
<h5>${tutorial.author}</h5>
<div>
Published: ${tutorial.publishDate}
</div>
<div>
Visits: ${tutorial.visits}
</div>
<hr/>
<div>
${tutorial.contents}
</div>
<a href="/topicsurl">Topics</a>
<a href="logout">Sign Out</a>
</body>
</html>
@RequestMapping("/logout")
public String logout(HttpSession session) {
7/9
day13.md 11/27/2021
session.invalidate();
return "logout";
}
Create webapp/WEB-INF/jsp/logout.jsp.
Usually String return value is viewName. Sometimes it can be forward or redirect request.
return "manage" --> FrontController --> viewResolver (prefix+suffix) --> forward req to manage.jsp -->
response is sent to the client.
return "redirect:manage" --> FrontController --> resp.sendRedirect("manage") --> Browser client pull
(new request) for /manage --> FrontController --> find method in @Controller for url /manage.
8/9
day13.md 11/27/2021
9/9
day14.md 11/28/2021
Java EE
Agenda
State management
Assignment discussion
Validations
Static resources
Localization & Internationalization
REST or Hibernate
Spring allows server side state management and client side state management.
HttpSession attributes
HttpSession session --> session.setAttribute() and session.getAttribute() can be used.
Spring bean with @Scope("session").
Request attributes --> spring Model is abstraction on request attributes.
To send data from controller to the view.
Model model --> model.addAttribute("key", value) and In JSP ${key}
Map<String,Object> model --> model.put("key", value) and In JSP ${key}
Also req.setAttribute() and req.getAttribute() can also be used.
Spring bean with @Scope("request").
Cookies --> resp.addCookie("key", "value") and @Cookie("key") String value
QueryString --> @RequestParam or Command object
Hidden Form Fields --> <input type="hidden" ...> and @RequestParam or Command
object
mvctutorials3
Copy project mvctutorials2 as mvctutorials3. Edit name & artifactId in pom.xml and update the Maven
project.
Create @Component class AuthenticatedUser and make its scope as @SessionScope.
@Autowired AuthenticatedUser bean into UserControllerImpl and TutorialControllerImpl.
Change UserControllerImpl.validate() method to.
@RequestMapping("/validate")
public String validate(Credentials cred) {
User user = userService.authenticateUser(cred.getEmail(),
cred.getPassword());
if(user == null)
return "failed";
authUser.setId(user.getId());
authUser.setName(user.getName());
1/4
day14.md 11/28/2021
authUser.setEmail(user.getEmail());
authUser.setRole(user.getRole());
if(user.getRole().equals("admin"))
return "redirect:manage";
return "redirect:topicsurl";
}
model.addAttribute("uname", authUser.getName());
Hello, ${uname}
model.addAttribute("role", authUser.getRole());
<c:choose>
<c:when test="${role == 'admin'}">
<a href="/manage">Manage</a>
</c:when>
<c:otherwise>
<a href="/topicsurl">Topics</a>
</c:otherwise>
</c:choose>
Assignment discussion
mvctutorial4
Copy project mvctutorials2 as mvctutorials4. Edit name & artifactId in pom.xml and update the Maven
project.
Refer assignment steps from day13.pdf.
Pending work:
Add New Tutorial
Delete Tutorial
Spring Validations
2/4
day14.md 11/28/2021
End user may enter wrong data while registration/sign in/data entry.
In "general" there are two ways of Validations
Client side Validations
Server side Validations
Database level Validations
HTML5 controls
<input type="text" required>
<input type="date" .../> or <input type="email" .../> or <input type="number"
.../>.
JS or jQuery framework for validation
Client side validations are faster and gives better user experience.
Client side validations can be compromized by the end user (disable JS, ...).
Spring MVC supports server side validations using "spring form tags".
It use standard annotations for the data validations (JSR 303).
@NotBlank -- should not be empty (primitive types and string)
@NotNull -- should not be null
@Min and @Max -- numeric values like age.
@DateTimeFormat -- desired date format
@Pattern -- Regular expression
@Size -- string length
@Email -- Email pattern check (internally use regex)
To process validations use @Valid on command/pojo object.
In Spring MVC also use @ModelAttribute and refer the object into spring form.
To collect the validation errors use BindingResult or Errors object as next argument (after command
object).
Copy project mvctutorials4 as mvctutorials5. Edit name & artifactId in pom.xml and update the Maven
project.
In pom.xml add validation starter.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3/4
day14.md 11/28/2021
Create folder structure for JS, CSS and/or Images under resources/static folder.
Create required js, css or image files into respective folders.
Use their links into JSP pages.
Example1:
Example2:
Example3: ...
4/4
day15.md 11/29/2021
Java EE
Agenda
Thymeleaf introduction
ORM
Hibernate architecture
Hibernate CRUD operations
Hibernate3 & Hibernate5 bootstrapping
SessionContext
Spring & Hibernate Integration
JSP limitations
Spring boot runs with "embedded" web server like tomcat/jetty. With executable jar, JSP files are not
accessible directly.
JBoss Undertow web server does not support JSPs.
Creating a custom error.jsp page does not override the default view for error handling. Custom error
pages should be used instead.
Thymeleaf - QuickStart
Thymeleaf vs JSP
Thymeleaf & JSP both can be used to build views in web applications.
Thymeleaf can be used in non-web context as well.
Email template
PDF template
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
1/6
day15.md 11/29/2021
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@Controller
public class HomeController {
@RequestMapping("/index") // url --> handlerMapping
public String index(Model model) {
model.addAttribute("curTime", new Date().toString());
return "home"; // view name --> viewResolver
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Home</title>
</head>
<body>
<h3>Welcome to Home</h3>
<span th:text="${curTime}"></span>
</body>
</html>
Eclipse --> Run --> Maven Buid --> Goal = packag --> Apply --> Run
On command prompt go to the target directory (where jar is created).
cmd> java -jar thmvc.jar
browser: http://localhost:8080/
cmd> Ctrl + C
DAC Course
Option 1: React Frontend + Spring REST Backend
Option 2: React Frontend + ASP.NET WebAPI/Core Backend
2/6
day15.md 11/29/2021
Thymeleaf config
@Configuration
@EnableWebMvc
public class ThymeleafConfiguration {
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
resolver.setContentType("text/html");
return viewResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(thymeleafTemplateResolver());
return templateEngine;
}
@Bean
public SpringResourceTemplateResolver thymeleafTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new
SpringResourceTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
3/6
day15.md 11/29/2021
}
}
ORM
Hibernate
https://docs.jboss.org/hibernate/orm/5.5/javadocs/
https://docs.jboss.org/hibernate/orm/5.5/userguide/html_single/Hibernate_User_Guide.html
Hibernate Architecture
@Entity
@Column(name="columnName")
private DataType fieldName;
If Column name is same as fieldName, then need not to mention name attribute of @Column.
@Column
private DataType fieldName;
In an @Entity class, if Column name is same as fieldName, no need to write even @Column.
If you want to add some field, that is not in table then mark it as @Transient.
@Entity
@Table(name="books")
class Book {
// all field names are same as column names, so no need to write @Column
@Id // primary key (compulsory)
private int id;
private String name;
4/6
day15.md 11/29/2021
@Temporal will convert RDBMS Date Time types into java.util.Date, java.util.Calendar,
java.util.LocalDate, java.util.LocalTime, etc.
@Entity
@Table(name="customers")
public class Customer {
@Id
private int id;
private String name;
private String email;
private String mobile;
private String address;
private String password;
@Temporal(TemporalType.DATE)
private Date birth;
}
If written on fields, hibernate initialize fields directly using reflection (e.g. session.get()).
If written on getters, hibernate initialize fields using corresponding setter methods. If any logic is
present in setter will be executed. Naming conventions must be followed for getter/setter.
Standard practice is to use these annotations on getters.
Create new Maven project. In pom.xml set Java version 11 and add dependencies hibernate-core and
mysql-connector-java.
Create resources/hibernate.cfg.xml to specify database params.
Write HbUtil class to create singleton SessionFactory (Hibernate 3).
Create Book class and do ORM mapping using annotations.
Add Book class mapping into hibernate.cfg.xml <mapping/>.
Create BookDao class and provide methods for findById(), save(), update(), deleteById(), findAll().
Write a main class and test all methods into main() method.
5/6
day15.md 11/29/2021
Hibernate 5 Bootstrapping
Copy Demo 10 as Demo 11. Rename artifactId & name in pom.xml and update the Maven project.
Modify HbUtil class to create singleton SessionFactory (Hibernate 5 bootstrapping).
Test all methods into main() method.
6/6
day19.md 12/25/2021
XML vs JSON
XML
<book>
<id>1</id>
<name>Abc</name>
<price>123.45</price>
</book>
JSON
{
"id": 1,
"name": "Abc",
1 / 20
day19.md 12/25/2021
"price": 123.45
}
JSON format
{
"name": "Nilesh",
"contact": {
"email": "nilesh@sunbeaminfo.com",
"mobile": "9527331338"
},
"age": 38,
"rating": 4.5,
"domains": [ "Enterprise apps", "Big Data", "Embedded", "Operating
Systems" ],
"experience": [
{
"company": "Seed",
"duration": "Aug 2001 to May 2003"
},
{
"company": "Freelance Trainer",
"duration": "Feb 2004 to May 2004"
},
{
"company": "Sunbeam",
"duration": "May 2004 to Oct 2021"
}
]
}
GET: http://localhost:8080/books
Request body: Empty
2 / 20
day19.md 12/25/2021
[
{ "_id": ..., "name": "...", "author": "...", "subject": "...",
"price": ... },
{ "_id": ..., "name": "...", "author": "...", "subject": "...",
"price": ... },
{ "_id": ..., "name": "...", "author": "...", "subject": "...",
"price": ... }
]
GET: http://localhost:8080/books/1
Request body: Empty
Response body: Book - 200
POST: http://localhost:8080/books
Request body:
Spring REST
RestTemplate is used to create applications that consume RESTful Web Services. The application can be
console application, web application or another REST service.
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
Creating RestTemplate using builder is a good practice. It can be used to customize restTemplate with
custom interceptors. It also enables application metrics and work with distributed tracing
4 / 20
day19.md 12/25/2021
Create a UriComponentsBuilder with one of the static factory methods (such as fromPath(String)
or fromUri(URI))
Set the various URI components through the respective methods (scheme(String),
userInfo(String), host(String), port(int), path(String), pathSegment(String...), queryParam(String,
Object...), and fragment(String).
Build the UriComponents instance with the build() method.
String url =
UriComponentsBuilder.fromHttpUrl(BOOKS_URL).path("/{id}").build().toUriStrin
g();
RequestEntity<> can be used to build request object in readable manner (method chaining).
@JsonInclude(Include.NON_NULL)
class Emp {
private int empno;
private String ename;
private String job;
@JsonProperty("salary")
private double sal;
private Double comm;
@JsonIgnore
private double income; // computed field
@JsonManagedReference
private Dept dept;
// ...
}
@JsonInclude(Include.NON_EMPTY)
class Dept {
private int deptno;
private String dname;
private String loc;
@JsonBackReference
private List<Emp> empList;
// ...
}
DTO classes
6 / 20
day19.md 12/25/2021
Helper methods can do conversions manually or use spring BeanUtils.copyProperties(). Note that
copyProperties() can copy only matching properties; remaining properties should be copied
manually.
Third party libraries can also be used for entity to DTO conversions e.g. ModelMapper,
MapStruct, etc. https://www.baeldung.com/java-performance-mapping-frameworks
Using Postman
Collections
Requests
Request headers & body
Response headers & body
Variables
Postman Console
Request handler method can catch exception and produce appropriate error response.
ResponseEntity<?> requestHandler() {
try {
// execute business logic and get the result
return ResponseEntity.ok(result);
} catch(Exception ex) {
// create custom error object/map and init it
return new ResponseEntity<Error>(error, HttpStatus.XXX);
}
}
Error handling logic can be implemented in a separate method in the controller annotated with
@ExceptionHandler.
7 / 20
day19.md 12/25/2021
ResponseEntity<?> requestHandler() {
try {
// execute business logic and get the result
return ResponseEntity.ok(result);
} catch(Exception ex) {
throw new CustomException(...);
}
}
@ExceptionHandler(CustomException.class)
ResponseEntity<?> handleException(CustomException ex) {
// create custom error object/map and init it
return new ResponseEntity<Error>(error, HttpStatus.XXX);
}
@RestController
class MyController {
ResponseEntity<?> requestHandler() {
try {
// execute business logic and get the result
return ResponseEntity.ok(result);
} catch(Exception ex) {
throw new CustomException(...);
}
}
// ...
}
@ControllerAdvice
class GlobalExceptionHandlers {}
@ExceptionHandler(CustomException.class)
ResponseEntity<?> handleException(CustomException ex) {
// create custom error object/map and init it
return new ResponseEntity<Error>(error, HttpStatus.XXX);
}
// ...
}
8 / 20
day19.md 12/25/2021
JavaScript - jQuery
NodeJS - Axios
Invoking spring REST services from ReactJS frontend.
CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to
indicate any origins (domain, scheme, or port) other than its own from which a browser should permit
loading resources.
The CORS mechanism supports secure cross-origin requests and data transfers between browsers and
servers.
Modern browsers use CORS in APIs such as XMLHttpRequest to mitigate the risks of cross-origin HTTP
requests.
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that let servers
describe which origins are permitted to read that information from a web browser.
CORS failures result in errors but for security reasons, specifics about the error are not available to
JavaScript. All the code knows is that an error occurred. The only way to determine what specifically
went wrong is to look at the browser's console for details.
Example
Request
Response
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
9 / 20
day19.md 12/25/2021
Server applicable may restrict resources/APIs to be accessed only from certain resources Access-
Control-Allow-Origin: https://myapp-front-end.com.
Spring boot application handle CORS with @CrossOrigin annotation on @Controller and/or
@RestController. It can also be used on individual request handler methods in controllers.
@CrossOrigin("*") // default is to allow all origins "*".
@CrossOrigin(origins = "https://myapp-front-end.com")
Spring AOP
AOP Terminologies
Aspect
Advice
JoinPoint
Pointcut
10 / 20
day19.md 12/25/2021
Target
Proxy
step 1: Copy demo04 (Banking demo) as demo12. In pom.xml change project name, artifactId and then
Maven - Update project.
step 2: In pom.xml, add dependency for AOP.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
// AccountImpl class
public void withdraw(double amount) {
if(logger != null)
logger.log("withdraw amount Rs. " + amount + " from account " + id);
if(this.balance - amount < 0)
throw new RuntimeException("Insufficient balance.");
this.balance = this.balance - amount;
}
@Aspect
@Component
public class AccountAspectImpl {
@Before("execution (* Account.deposit(..))")
public void beforeDeposit(JoinPoint jpt) {
Account acc = (Account) jpt.getTarget();
11 / 20
day19.md 12/25/2021
@AfterReturning("execution (* Account.withdraw(..))")
public void afterWithdrawSuccess(JoinPoint jpt) {
System.out.println("Withdraw() operation sucessful.");
}
@AfterThrowing("execution (* Account.withdraw(..))")
public void afterWithdrawFailure(JoinPoint jpt) {
System.out.println("Withdraw() operation failed.");
}
@After("execution (* Account.withdraw(..))")
public void afterWithdraw(JoinPoint jpt) {
System.out.println("Withdraw() was called.");
}
@Around("execution (* Account.deposit(..))")
public Object aroundDeposit(ProceedingJoinPoint jpt) throws Throwable {
System.out.println("deposit pre-processing!");
// pre-processing
long t1 = System.currentTimeMillis();
// @Before is called
Object result = jpt.proceed();
// @After is called
// post-processing
long t2 = System.currentTimeMillis();
long diff = t2 - t1;
System.out.println("Time taken in ms: " + diff);
System.out.println("deposit post-processing!");
return result;
}
@After("execution (* Account.set*(..))")
public void afterSetter(JoinPoint jpt) {
System.out.println("Setter is called: " + jpt.getSignature());
}
@AfterReturning("accTransaction()")
public void afterTransaction(JoinPoint jpt) {
System.out.println("Sending Email on Transaction: " +
jpt.getSignature());
}
}
12 / 20
day19.md 12/25/2021
// ...
@Configuration
public class BankConfig {
@Bean
public Account acc() {
Account a = new AccountImpl(101, "Saving", 10000.0);
return a;
}
// ...
}
step 6: In main class access "acc" bean and invoke deposit() and withdraw().
System.out.println(acc);
acc.deposit(2000);
System.out.println(acc);
acc.withdraw(5000);
System.out.println(acc);
acc.withdraw(8000);
System.out.println(acc);
Spring Security
Authentication
Who are you?
13 / 20
day19.md 12/25/2021
Identity proof
Knowledge based authentication
Username and password
Secret question
Combination with other details
Single-Sign-on
Possession based authentication
Email/SMS code
QR-Code authentication using Mobile
Swipe cards/RSA tokens
Bio-metric
Multifactor authentication
Combination of multiple options
Authorization
What you are allowed to do?
Role based
Different users in application have different access - Banking System
Cashier
Branch Manager
Loan officer
Principal
User of system identified by process of authentication i.e. Currently logged in user/account
Principal is stored by spring application to track user.
Granted Authority
Well-defined actions for which user is authorized/allowed to.
Banking users are authorized for differnent actions.
Cashier
view customer balance
deposit/withdraw from customer account
manage/tally daily cash
Branch Manager
approve resources for branch
assign/monitor responsibilities
review branch business
Authorities are fine-grained
Roles
Group of authorities (multiple authorities)
Coarse-grained authorities/permissions
Helps assigning set of authorities to users on similar role/position.
ROLE_CASHIER
ROLE_BRANCH_MANAGER
ROLE_LOAN_OFFICER
14 / 20
day19.md 12/25/2021
Filters in this chain intercept each request and validate access to resource against Principal/Granted
authority.
These filters also perform default actions (login, logout, store principal, invalidate session/cookie) as
appropriate.
Step 1: Create Spring Boot application with Web, Thymeleaf and Security starter.
In application.properties
spring.security.user.name=sunbeam
spring.security.user.password=infotech
Username/Password Authentication
AuthenticationManager:
Authentication:
Represents the token for an authentication request or for an authenticated principal once the
request has been processed by the AuthenticationManager.
15 / 20
day19.md 12/25/2021
It holds credentials before login and principal object corresponding to successfully logged in
user.
Typically principal object is simply UserDetails object - holding user information and authorities.
Authentication will be typically stored in a thread-local SecurityContext managed by the
SecurityContextHolder by the authentication mechanism.
Methods:
getCredentials()
getPrincipal()
getAuthorities()
isAuthenticated()
setAuthenticated()
Available Authentication implementations:
UsernamePasswordAuthenticationToken
JwtAuthenticationToken
OAuth2AuthenticationToken
...
AuthenticationManagerBuilder:
AuthenticationProvider:
UserDetailsService:
16 / 20
day19.md 12/25/2021
UserDetails:
Step 1: Create Spring Boot application with Web, Thymeleaf and Security starter.
Step 2: Create HomeController and index.html for mapping /. Can also create additional mappings.
Authorization
HttpSecurity:
Step 1: Create Spring Boot application with Web, Thymeleaf and Security starter.
Step 2: Create HomeController and index.html for mapping /. Can also create mappings & pages for
/user and /admin.
17 / 20
day19.md 12/25/2021
Step 5: Test application with configured user and password of different roles
JDBC Authentication
Step 1: Create Spring Boot application with Web, Thymeleaf, H2, JDBC and Security starter.
Step 2: Create HomeController and index.html for mapping /. Can also create mappings & pages for
/user and /admin.
Step 3: Create schema.sql and data.sql to create H2 database schema.
schema.sql --> users table and roles table
data.sql --> created users and roles
Step 4: Implement SecurityConfig class inherited from WebSecurityConfigurerAdapter.
Add @EnableWebSecurity on the class.
Provide a BCryptPasswordEncoder bean.
Step 5: Override void configure(HttpSecurity http) to set up Authorization in SecurityConfig.
Allow / for all users.
Allow /user only for ROLE_USER.
Allow /admin only for ROLE_ADMIN.
Step 6: Override void configure(AuthenticationManagerBuilder auth) to set up JdbcAuthentication.
Attach DataSource.
Provide usersByUsernameQuery() that return username, password, enabled columns.
Provide authoritiesByUsernameQuery() that return username, authority columns.
Step 7: Test application with user and password (given in data.sql) of different roles.
Step 1: Create Spring Boot application with Web, Thymeleaf, H2, Spring Data JPA and Security starter.
Step 2: Create HomeController and index.html for mapping /. Can also create mappings & pages for
/user and /admin.
Step 3: Create schema.sql and data.sql to create H2 database schema.
schema.sql --> users table and roles table
data.sql --> created users and roles
Step 4: In application.properties, do necessary JPA config.
Step 5: Create User & Role entity classes. Also create UserRepository class.
Step 6: Implement UserDetails in a user-defined class (ShopUser) to convert User entity in required
form.
Step 7: Implement UserDetailsService in a user-defined class (ShopUserDetailsService).
loadUserByUsername() using JPA repository. Convert return value into user-defined UserDetails
(inherited) class.
Step 8: Implement SecurityConfig class inherited from WebSecurityConfigurerAdapter.
Add @EnableWebSecurity on the class.
Provide a BCryptPasswordEncoder bean.
Step 9: Override void configure(HttpSecurity http) to set up Authorization in SecurityConfig.
Allow / for all users.
Allow /user only for ROLE_USER.
Allow /admin only for ROLE_ADMIN.
18 / 20
day19.md 12/25/2021
JWT is a open standard (RFC 7519) to transfer data amoung two parties securely.
Spring Web MVC applications store Authentication token into HttpSession, so that authorization info
can be used over sub-sequent requests.
Spring REST services (typically micro-services) are stateless and do not use state management
mechanisms like session/cookie.
JWT is used to maintain client state on client side itself like cookies (but signed -- cannot be tampered).
JWT is signed (encrypted) web token that cannot be tampered by the user (until it has secret).
JWT has three parts
Header: Encryption algorithm & token type (JWT)
Payload: JSON data to be stored.
Signature: JWT token secret
JWT tokens can be inspected at jwt.io.
JWT tokens can be generated/interpreted using specialized libraries.
Apache JJWT.
JWT is designed for authorization after authentication process is completed keeping desired details into
JWT payload.
Typical process:
Client sends credentials to the server.
Server authenticate the user, put client identity into JWT payload and send to client.
Client store JWT information into local storage or cookie or some other mechanism.
While accessing a protected resource, client sends JWT to the server (typically in header).
Server get JWT, validates it and retrieve the payload information.
Based on client identity server allows/denies access to the resource.
Few considerations
JWT (payload) can be easily decrypted. So never store sensitive client information in it.
JWT can be stolen i.e. another client may access protected resources using JWT tokens of some
other client.
JWT cannot be disabled (unlike session), but can be expired.
JWT Authentication/Authorization
Step 1: Create Spring Boot application with Web, Thymeleaf, H2, Spring Data JPA, Security starter, jjwt.
Step 2: Create HomeController -- @RestController.
/ mapping returns "Home"
/user mapping returns "User " + username
/admin mapping returns "Admin " + username
Step 3: Create schema.sql and data.sql to create H2 database schema.
schema.sql --> users table and roles table
19 / 20
day19.md 12/25/2021
20 / 20