Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
13 views

AdvanceJava Day

Uploaded by

Akshay Jawale
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

AdvanceJava Day

Uploaded by

Akshay Jawale
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

day01.

md 7/12/2021

Java EE (Advanced Java)


Agenda
Module Introduction
STS IDE
Java EE
HTTP Protocol
Java Web Server
Tomcat Web Server

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

Theory: 40 marks -- CCEE


Lab: 40 marks -- Spring Boot + JPA
Internals: 20 marks
Quiz
Case study

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

e.g. Browser, Mobile applns, Embedded applns, etc.


Web application/site: Set of web pages/resources served over the internet (using HTTP protocol).
HTTP protocol
Application layer protocol (in ISO-OSI layers) depending on TCP protcol.
TCP protocol
Connection oriented protocol
Stateful protocol
Reliable (Acknowlegement)
HTTP protocol
Connection-less protocol
State-less protocol
Request Response model

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

Java Web Server

Java Web Server = Web container + Extra services


Web container -- Required for executing Servlet & JSP.
Extra servies -- SSL, JNDI, Connection pool, etc.
e.g. Tomcat, Lotus, ...

Java Application Server

Java Application Server = Web container + Extra services + EJB container


Web container -- Required for executing Servlet & JSP.
Extra servies -- SSL, JNDI, Connection pool, etc.
EJB container -- Required for executing EJB, Message Beans (Heavy-weight).
e.g. JBoss, WebSphere, WebLogic, ...

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

webapps: Web applications are deployed here (Hot deployment folder)


work: Contains temp files (We will discuss while JSP programming)
logs: Contains execution logs

4/4
day02.md 7/13/2021

Java EE (Advanced Java)


Agenda
Java EE application directory structure
Java Servlets
HttpServletRequest & HttpServletResponse
Inter-servlet communication
State Management

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.

Java EE application directory structure


Web application: Set of web pages/resources
Web Pages
Static web pages: Static contents e.g. HTML pages.
No code execution at server side.
Dynamic web pages: Dynamic contents produced when request is done
Java code executed on server side to produce HTML output.
Most commonly Business logic, Database connectivity, ...
Java EE Web application directory structure (part of specification -- applicable for all web servers)

Hello Web Application

Create directory "helloweb" in tomcat/webappps.


helloweb
1/5
day02.md 7/13/2021

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

Called once by web container for each request.


For each request:
Web container create HttpServletRequest object (representing HTTP request).
Web container create HttpServletResponse object (to represent HTTP response).
Calls service() method of the servlet.
Convert response object into HTTP response.
Programmer should override this method to implement Business logic and response
generation logic.

javax.servlet.GenericServlet class (abstract)

Default implementation of init()


Attach ServletConfig object with current Servlet object.
Default implementation of destroy()
Do not provide implementation of service() -- remains abstract
GenericServlet is protocol independent servlet
service() handling is always protocol dependent.

javax.servlet.HttpServlet class (abstract)

init() implementation
destroy() implementation
service() implementation -- to handle HTTP request

abstract class HttpServlet extends GenericServlet ... {


@Override
public void init(ServletConfig config) ... {
super.init(config);
// ...
}
@Override
public void destroy() {
// ...
super.destroy();
}
@Override
public void service(ServletRequest req, ServletResponse resp) ... {
// get data from HTTP request and load into req object.
this.service((HttpServletRequest)req, (HttpServletResponse) resp);
// get data from resp object and convert into HTTP response.
}
protected void service(HttpServletRequest req, HttpServletResponse resp)
... {
String method = req.getMethod(); // GET, POST, PUT, DELETE, HEAD,
TRACE, OPTIONS
if(method.equals("GET"))
this.doGet(req, resp); // if overridden by user-defined servlet,
it's doGet() will be called
else if(method.equals("POST"))
this.doPost(req, resp); // if overridden by user-defined
servlet, it's doPost() will be called
3/5
day02.md 7/13/2021

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(...);
}
// ...
}

User-defined Servlet class

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>");
}
}

Command Line Compilation of Servlet

Continue with helloweb application (directory struct already created in tomcat/webapps).


Create directory WEB-INF/src.
Save MyServlet.java into WEB-INF/src.
Compile MyServlet.java into MyServlet.class

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

Hello Servlet on Eclipse

Configure Eclipse with Apache Tomcat (once per workspace).


Window --> Server --> Runtime --> Add New Tomcat 9.0 (as given in PDF)
Create new project --> Web --> Dynamic Web Project --> demo01
Check "Generate web.xml deployment descriptor"
Create MyServlet.java under src.
Run As --> Run on Server --> Select Tomcat (Check Always run on this server).
Next ... Finish
Browser: http://localhost:8080/demo01/hello

5/5
day03.md 7/14/2021

Java EE
Agenda
Servlet init-param
Servlet load-on-startup
Inter-servlet communication/navigation
State management

Annotation vs XML config


XML based config
Need not to recompile the whole project.
If config has mistake, then deployment will fail. (No compilation in adavance).
Annotation based config
Java code is compiled for syntax errors in advanced, so less chances of failure while deployment.
Need to recompile the project.
Nowadays preferred in industry.

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".

// in doGet(), doPost(), ... methods


String dbUrl = this.getInitParameter("DB_URL");
// ...

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);

This is faster than HTTP redirection.

Browser is not aware of the navigation.

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

Client Side State Management

The state/info of client is stored on client machine


Less memory is needed at the server side
Less secure, client can access and/or modify
Options: Cookie, QueryString, Hidden Form Fields

Server Side State Management

The state/info of client is stored on server machine


Large memory is needed at the server side
More secure, client cannot directly access
Options: Session, Application

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

Cookie c = new Cookie("key", "value");


// c.setMaxAge(secs); // to make cookie persistent
resp.addCookie(c);

To receive cookie and get data

3/4
day03.md 7/14/2021

Cookie[] arr = req.getCookies();


for(Cookie c : arr) {
if(c.getName().equals("key")) {
String value = c.getValue();
// ...
}
}

Cookie methods
Refer java docs

Cookie(String name, String value);


String getName();
String getValue();

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

Cookie c = new Cookie("uname", name);


c.setMaxAge(0);
resp.addCookie(c);

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.

String uname = "";


Cookie[] arr = req.getCookies();
for(Cookie c: arr) {
if(c.getName().equals("uname"))
uname = c.getValue();
}

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

Object getAttribute(String key);


void invalidate();
boolean isNew();
String getId();
To get session object
HttpSession session = req.getSession();
to change session timeout: web.xml in <web-app>

<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

In case cookies disabled, sessionid can be maintained using url.


resp.encodeURL() and resp.encodeRedirectURL() methods are used to embed sessionid into the url.
e.g. http://server:port/app/page;jsessionid=374334

ServletContext
For each web application, web container creates a singleton object called as "ServletContext" during
application deployment.

This object is used

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).

ServletContext object can be accessed using

req.getServletContext()

2/3
day04.md 7/15/2021

session.getServletContext()
config.getServletContext()
this.getServletContext() // In Servlet class

To save and retrieve data from the ServletContext

void setAttribute(String key, Object value);


Object getAttribute(String key);

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:

String colorValue = context.getInitParameter("color");

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

void contextInitialized(ServletContextEvent e);


void contextDestroyed(ServletContextEvent e);

interface HttpSessionListener

void sessionCreated(HttpSessionEvent e);


void sessionDestroyed(HttpSessionEvent e);

interface HttpSessionAttributeListener:

void attributeAdded(HttpSessionBindingEvent e);


void attributeRemoved(HttpSessionBindingEvent e);
void attributeReplaced(HttpSessionBindingEvent e);

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.

How to use listeners?


step1: write a class implementing required listener
step2: write the appropriate logic into appropriate method
step3: inform web container about this listener in web.xml or using annotation @WebListener

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 Life cycle

step 1. Translation Stage:


When first request is made for the JSP page, it will be loaded by the web container inside JSP
engine.
JSP engine translate the JSP page into a servlet's java code. This .java file can be found in
tomcat's "work" folder.
If there is any error in JSP syntax (e.g. scriptlets), then this stage fails.
step 2. Compilation Stage:
The translated servlet's .java file will be compiled into a .class file at runtime.
If there is any java syntax error, then this stage fails.
2/5
day05.md 7/16/2021

step 3. Instantiation (Loading) Stage:


The .class file will be loaded and object of the translated servlet will be created.
Immediately after this init method of the JSP i.e. jspInit() will be executed.
If this method throws any exception, this stage fails.
This stage is also called as Loading or Initialization stage.
step 4. Request Handling Stage:
All above stages are done only for the first request of the JSP file; However this stage is executed
for each request.
For each request, _jspService() method is executed (which is made up of all the scriptlet and
expressions in the JSP file).
step 5. Destruction Stage:
When servlet object is no longer used or web container is going down, jspDestroy() method will
be executed after which servlet object will be garbage collected.

JSP syntax

directive <%@ .... %>

<%@page language="java" import="java.util.*, java.io.*" ..%>


mainly controls servlet translation
<%@include file="file.ext" %>
adding external html or jsp file statically.
<%@taglib .... %>
used for custom and third-party tags

declaration <%! .... %>

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

scriptlet <% .... %>

used to write java statement(s) to be executed per request.


all code written here will become part of _jspService() method during translation phase.

expression <%= .... %>

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.

comment <%-- .... --%>

Server side comment -- not visible to the client - HTML source


<!-- ... --> HTML client comment -- visible to the client - HTML source

JSP Example

3/5
day05.md 7/16/2021

class HelloServlet extends HttpServlet {


private int count;
@Override
public void init(ServletConfig config) throws ServletException {
count = 0;
System.out.println("HelloServlet.init() called");
}
@Override
public void destroy() {
System.out.println("HelloServlet.destroy() called");
}
@Override
public void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
count++;
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Even Odd</title>");
out.println("</head>");
out.println("<body>");
if(count % 2 == 0)
out.println("<h4>Even Count = " + count + "</h4>");
else
out.println("<h4>Odd Count = " + count + "</h4>");
out.println(new Date().toString());
out.println("</body>");
out.println("</html>");
}
}

<%@ page contentType="text/html" import="java.util.Date" %>


<html>
<head>
<title>Even Odd</title>
</head>
<body>
<%! // data/method members of generated servlet code (declaration)
private int count;
%>

<%! // data/method members of generated servlet code (declaration)


public void jspInit() {
count = 0;
System.out.println("HelloServlet.init() called");
}
public void jspDestroy() {
System.out.println("HelloServlet.destroy() called");
}
%>
4/5
day05.md 7/16/2021

<%-- scriptlet syntax contains java statement(s) to be executed for


each request --%>
<%
count++;
System.out.println("service() is called.");
%>

<%-- expression syntax contains java expression whose result will be


embedded in produced html --%>
<% if(count % 2 == 0) { %>
<h4>Even Count = <%= count %> </h4>
<% } else { %>
<h4>Odd Count = <%= count %> </h4>
<% } %>

<%
out.println(new Date().toString());
%>
<br/>
<%= new Date().toString() %>
</body>
</html>

JSP good practices

Never mix mark-up code and java code.


JSP with scriptlets, declarations and expressions are considered to be BAD jsp.
Ideal JSP is always zero-scriptlet JSP.
JSP --> presentation logic
Java Beans --> business logic

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

Custom Error Pages


To display exceptions separate pages can be created with <%@ page isErrorPage="true" %>
You can access "exception" object in such pages.
These page can be linked to other JSP page with <%@ page errorPage="error.jsp" %>
1/5
day06.md 7/17/2021

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.

JSP Implicit Objects


Few objects can be directly accessible in JSP scriptlet and expressions (Request handling stage --
_jspService() method) without declaring them. They are JSP implicit objects.
Internally these objects are local variables/arguments of _jspService().

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

JSP Standard Actions


Refer slides.
JSP built-in tags used for specific tasks. Reduces Java code in JSP pages.
Standard actions is part of Java EE JSP specifications.

jsp:plugin & jsp:fallback

These tags are used to embed applets (and other plugins like flash) into jsp pages.

<jsp:plugin type="applet" code="MyApplet.class" codebase="/application"


width="200"
height="300">

2/5
day06.md 7/17/2021

<jsp:fallback>Applet Not Loaded</jsp:fallback>


</jsp:plugin>

This code will be internally converted into html's or tag.

jsp:forward, jsp:include and jsp:param

Inter-servlet communication

<jsp:forward page="pageurl"/>
<%-- OR --%>
<jsp:include page="pageurl"/>

Will get converted into following java code

RequestDispatched rd = req.getRequestDispatcher("pageurl");
rd.forward(req, resp);
// OR
rd.include(req, resp);

jsp:include is used to for dynamic inclusion of the file.

Request param can be passed from page1.jsp to page2.jsp.

<jsp:forward page="page2.jsp">
<jsp:param name="key1" value="value1"/>
</jsp:forward>

// in page2.jsp
String val = request.getParameter("key1");

JSP & Java Beans


Rules to write Java Beans

Write a simple java class having following members:


1. one or more fields
2. param less constructor
3. getter/setter methods (proper camel case)
4. one or more business logic method (any name)

Standard actions for java beans

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

<jsp:useBean id="ub" class="sunbeam.beans.UpperCaseBean1"


scope="page" />

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

page --> PageContext attribute --> smallest & default scope.


accessible in current request to current page.
request --> HttpServletRequest attribute
accessible in all pages to which current request is forwarded/included.
session --> HttpSession attribute
accessible in all requests to all pages for current user.
application --> ServletContext attribute --> highest scope.
accessible in all requests to all pages for all users.

jsp:setProperty

Example

<jsp:setProperty name="obj" property="propName"


value="fix_value"/>

4/5
day06.md 7/17/2021

<jsp:setProperty name="obj" property="propName"


param="req_param"/>

<jsp:setProperty name="obj" property="*"/>

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

<jsp:getProperty name="obj" property="propName"/>

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

Also called as "Model-View" Architecture.


View -> Presentation Logic -> JSP pages
Model -> Business Logic / Data Transfer Objects -> Java Beans
Used for very small web applications

Model II architecture

Also called as "Model-View-Controller" Architecture.


Used for huge web applications
e.g. Third party frameworks like struts, spring, etc.

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.

Maven Core Concepts

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

Maven check the dependencies needed for your project.


Dependencies are external JAR files (Java libraries) that your project uses.
If the dependencies are not found in the local Maven repository, Maven downloads them from a central
Maven repository and puts them in your local repository.
Maven add all dependencies into current project classpath.
Dependency scopes
compile: This is the default scope (when no other scope is given).
provided: Dependencies that are provided at runtime by JDK or a container. These jars are not
deployed in final project archive. Example: java-ee api
runtime: The dependencies with this scope are required at runtime, but they're not needed for
compilation of the project code. Example: jdbc driver jars
test: Only present for test and execution classpaths. Example: JUnit.

Build life cycle, Phases & Goals

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.

Build Life Cycles

2/3
day07.md 7/20/2021

Maven has built-in build life cycles. These are:


default: related to compiling and packaging your project.
clean: related to removing temporary files from the output directory.
Life cycle is further divided into phases.
When any phase is given, all phases before it are executed.

Default Build Life Cycle Phases

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/Spring Boot - Resources

Spring & Spring Boot Documentation


Book: Spring in Action

Spring techologies overview

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/)

Spring vs Spring Boot

Spring is lightweight comprehensive framework that simplifies Java development.

Why Spring

Spring is lightweight. The basic version of Spring framework is around 2MB.


Good programming practices based on interfaces and POJOs.
Spring Beans vs Java Beans
Java bean is a java POJO class with one or more business logic methods.
Typically Java beans are created in JSP pages and handled in JSP using actions & EL.
1/6
day10.md 11/24/2021

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

EJB container: EJB life-cycle

Spring XML configuration BoxImpl demo (demo01)

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).

Spring Annotation configuration BoxImpl demo (demo02)

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

Why Spring Boot

Provide a radically faster and widely accessible "Quick Start".


Very easy to develop production grade applications.
Reduce development time drastically.
Increase productivity.
Spring Boot CLI (https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-
cli.html)
Spring Initializr (https://start.spring.io/)
IDE support - Eclipse STS
Build tools - Maven/Gradle support
Managing versions of dependencies with starter projects.
Set of convenient dependency descriptors
Hierarchially arranged so that minimal dependecies to be added in application
e.g. spring-boot-starter-web
spring-web
spring-webmvc
spring-boot-starter
spring-core
spring-context
spring-boot-autoconfigure
spring-boot-starter-logging
log4j-to-slf4j
jul-to-slf4j
spring-boot-starter-json
jackson-databind
spring-boot-starter-tomcat
tomcat-embed-core
tomcat-embed-websocket
jakarta.el
hibernate-validator
No extra code generation (boiler-plate is pre-implemented) and No more XML config.
Minimal configuration required.
Ready to use in-memory/embedded databases, ORM/JPA, MVC/REST, ...
Opinionated configuration, yet quickly modifiable for different requirements.
Easy/quick integration with standard technologies/frameworks.
Examples:
Web applications -- Tomcat
ORM -- Hibernate
4/6
day10.md 11/24/2021

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.

Spring Boot BoxImpl demo (demo03)

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

Combination of three annotations


@ComponentScan
Auto detection of stereo-type annotated beans e.g. @Configuration, @Controller,
@Component, @Service, @Repository, ...
By default basePackage is to search into "current" package (and its sub-packages).
@ComponentScan("other.package") can be added "explicitly" to restrict the search of
beans into given package.
@Configuration
Spring annotation configuration to create beans.
Contains @Bean methods which create and return beans.
@Configuration classes are also auto-detected by @ComponentScan
@EnableAutoConfiguration
@EnableAutoConfiguration annotation
Spring @Configuration -- create the beans
Intelligent and automatic configuration
@Conditional beans
@ConditionalOnClass
@ConditionalOnMissingBean

SpringApplication class

Entrypoint of Spring boot application


main() method is called by JVM.
SpringApplication.run() does following
Create an ApplicationContext instance
Prepare spring container for spring bean life-cycle management
Create all singleton beans
Execute CommandLineRunner if available.

5/6
day10.md 11/24/2021

Console application.
By default take bean config from @Configuration classes.

Demo 04

step 1: interface Logger


step 2: class ConsoleLoggerImpl implements Logger -- implement log() method
step 3: class FileLoggerImpl implements Logger -- implement log() method
step 4: interface Account
step 5: class AccountImpl implements Account
step 6: Add Logger dependency into AccountImpl and provide getter/setter for the same. Also add
getter/setter for Logger into Account interface. In deposit() and withdraw() log the transaction message.
step 7: Create AppConfig class and create beans of Account, ConsoleLoggerImpl and FileLoggerImpl.
step 8: In main class @Autowired ApplicationContext ctx.
step 9: Inherit main class from CommandLineRunner and implement its run method.
9.1: Get all bean objects using ctx.getBean().
9.2: Invoke deposit() / withdraw() on account object. Execute the program. Note that logging is
not done (because acc.logger is not initialized).
9.3: Now set consoleLogger using acc.setLogger() before deposit()/withdraw() call. Execute the
program. Note that logging is done on console (because acc.logger points to ConsoleLoggerImpl
object).
9.4: Now set fileLogger using acc.setLogger() before deposit()/withdraw() call (instead of
consoleLogger). Execute the program. Note that logging is done in the file (because acc.logger
points to FileLoggerImpl object).

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

Demo 05 (Strereo-type annotations and @Value)

step 0: Create new "Spring Starter Project". Fill all details.


step 1: interface Logger
step 2: class ConsoleLoggerImpl implements Logger -- implement log() method
step 3: class FileLoggerImpl implements Logger -- implement log() method
step 4: Declare ConsoleLoggerImpl and FileLoggerImpl as @Component.
step 5: resources/demo.properties
log.filePath=application.txt
step 6: Use @Value("${log.filePath}") in FileLoggerImpl on "logFilePath" field.
step 7: On AppConfig class use @PropertySource("classpath:demo.properties"). Need not declare
@Bean methods in it (for now).
step 8: In main test Console Logger and File Logger.

ConfigurationProperties

Demo 05 (ConfigurationProperties)

step 9: interface Account


step 10: class AccountImpl implements Account
step 11: Add Logger dependency into AccountImpl and provide getter/setter for the same. Also add
getter/setter for Logger into Account interface. In deposit() and withdraw() log the transaction message.
step 12: Declare Account a1 and a2 properties into demo.properties. Example:
acc1.id = 101
acc2.id = 202
step 13: In AppConfig class create a1 & a2 @Bean with appropriate
@ConfigurationProperties(prefix="????").
In main() test a1 and a2.

Auto-wiring

Demo 05 (Auto-wiring)

Test 1

1/4
day11.md 11/25/2021

Comment @Component for ConsoleLoggerImpl and FileLoggerImpl.


Use @Autowired for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: Error - no bean found for auto-wiring "logger".

Test 2

Comment @Component for ConsoleLoggerImpl and FileLoggerImpl.


Use @Autowired(required=false) for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: No Error but logger is not auto-wired, so no deposit() log produced.

Test 3

Mark @Component for FileLoggerImpl. Comment @Component for ConsoleLoggerImpl.


Use @Autowired for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: No error. File logger is autowired and deposit() log added into the log file. This is
auto-wiring by type - No conflict because there is single bean of Logger type.

Test 4

Mark @Component for both ConsoleLoggerImpl and FileLoggerImpl.


Use @Autowired for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: Error - Expected single bean for "logger" found 2 beans. Either use @Primary or
@Qualifier.

Test 5

Mark @Component for FileLoggerImpl and @Component("logger") for ConsoleLoggerImpl.


Use @Autowired for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: No error. Console logger is autowired and deposit() log displayed on console. This is
auto-wiring byName.

Test 6

Mark @Component for ConsoleLoggerImpl and FileLoggerImpl.


Mark @Primary to FileLoggerImpl.
Use @Autowired for AccountImpl class's "logger" field.
In main() test Account a1 deposit().
Expected output: No error. File logger is autowired and deposit() log added into the log file. Note that
@Primary takes precedence over auto-wiring byName.

Test 7

Mark @Component from ConsoleLoggerImpl and FileLoggerImpl.


2/4
day11.md 11/25/2021

Use @Autowired and @Qualifier("consoleLoggerImpl") for AccountImpl class's "logger" field.


In main() test Account a1 deposit().
Expected output: No error. Console logger is autowired and deposit() log is displayed on console. Note
that @Qualifier takes precedence over @Primary.

Spring Bean Life Cycle

Demo 06 (Bean life cycle)

step 1: interface Box (with business logic calcVolume(), calcSurfaceArea())


step 2: class BoxImpl implements Box, InitializingBean, DisposableBean, BeanNameAware,
ApplicationContextAware
step 3: Add @PostConstruct and @PreDestroy methods
step 4: create @Configuration AppConfig class
create BoxImpl bean "b" in a @Bean method
step 5: class CustomBeanPostProcessorImpl implements BeanPostProcessor
Mark this as @Component in AppConfig.
Examples of pre-defined BeanPostProcessor: BeanValidationPostProcessor,
InitDestroyAnnotationBeanPostProcessor, etc.
step 6: Execute the application and understand bean life cycle.

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

Sensor interface - int readValue();


class TemperatureSensor implements Sensor
readValue() returns random number between 10 to 30.
class HumiditySensor implements Sensor
readValue() returns random number between 40 to 100.
ReadingSender interface - void send(int reading);
class TcpSender implements ReadingSender
send() print reading on console with "Sending over TCP".
class HttpSender implements ReadingSender
send() print reading on console with "Sending over HTTP".
class RestSender implements ReadingSender
send() print reading on console with "Sending over REST".
class SoapSender implements ReadingSender

3/4
day11.md 11/25/2021

send() print reading on console with "Sending over SOAP".


In each sender implementation @Autowired some fixed Sensor implementation using @Qualifier.
Make HttpSender as @Primary
In main() get bean of type ReadingSender (using ctx.getBean()) and call it's method. Test the output.
In main class get bean of type TcpSender (using ctx.getBean()) and call it's method. Test the output.
In main class declare field @Autowired ReadingSender restSender and call it's method. Test the output.
In main class declare field @Autowired ReadingSender sender with @Qualifier of SoapSender and call
it's method. Test the output.

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

Spring Bean Scopes

Demo 07 (Singleton & Prototype)

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

Demo 07 (Prototype bean inside Singleton bean)

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.

Demo 07 (Prototype bean inside Singleton bean)

step 6: Implement Inner2 as Prototype bean and Outer2 as Singleton bean.


step 7: Inherit Outer2 from ApplicationContextAware and return Inner2 bean from getInner() method
(using ctx.getBean()).
step 8: Create Outer2 bean in main() and try calling getInner() multiple times.
Note that:
Outer2 bean is created at the start of application.
Multiple calls to getInner() returns different (new) Inner2 bean reference.

1/5
day12.md 11/26/2021

Demo 07 (Prototype bean inside Singleton bean)

step 9: Implement Inner3 as Prototype bean and Outer3 as Singleton bean.


step 10: Return null from getInner() method and mark that method as @Lookup.
step 11: Create Outer3 bean in main() and try calling getInner() multiple times.
Note that:
Outer3 bean is created at the start of application.
Multiple calls to getInner() returns different (new) Inner3 bean reference.

Spring Boot JDBC Integration

Demo 08 (Tutorials & Login DAO + Service layer)

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

@Autowired on the constructor.


step 17: Implement methods findAll(), findByTopicId(), findById(), incrementVisitCount() in
TutorialDaoImpl.
step 18: In TutorialServiceImpl class add tutorialDao field and @Autowired it (field-based DI).
step 19: Implement methods findAll(), findByTopicId(), findById(), incrementVisitCount() in
TutorialServiceImpl, which in turn call respective methods in TutorialDaoImpl.
step 20: In main class @Autowired tutorialService and test its methods one by one.

Spring Web MVC

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.

Spring Web MVC Flow

DispatcherServlet receives the request.


DispatcherServlet dispatches the task of selecting an appropriate controller to HandlerMapping.
HandlerMapping selects the controller which is mapped to the incoming request URL and returns the
(selected Handler) and Controller to DispatcherServlet.
DispatcherServlet dispatches the task of executing of business logic of Controller to HandlerAdapter.
HandlerAdapter calls the request handler method of @Controller.
Controller executes the business logic, sets the processing result in Model and returns the logical name
of view to HandlerAdapter.
DispatcherServlet dispatches the task of resolving the View corresponding to the View name to
ViewResolver. ViewResolver returns the View Path mapped to View name.
DispatcherServlet dispatches the rendering process to View class / View Engine.
It renders view with Model data and returns the response.

Demo 09 (Simple MVC)

3/5
day12.md 11/26/2021

New -- Spring Starter Project


Fill project details
Spring Starter Dependencies
Spring Web
Dev Tools
Finish
In pom.xml add dependencies for JSP & JSTL.

<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>

In application.properties add following properties

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

Create class com.sunbeam.controllers.WelcomeController class.

@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
}
}

Create folder structure for JSP pages "webapp/WEB-INF/jsp" under src/main.


Create webapp/WEB-INF/jsp/index.jsp.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Home</title>
4/5
day12.md 11/26/2021

</head>
<body>
<h1>Welcome to Spring MVC</h1>
<h3>Sunbeam Infotech</h3>
<p>
${curDate}
</p>
</body>
</html>

Run as Spring Boot Application.


Browser: http://localhost:8080/welcome

5/5
day13.md 11/27/2021

Java EE
Agenda
Spring Web MVC
Request handler methods
using HTML tags
using Spring tags
State Management

Spring Web MVC


Request handler methods

Methods in @Controller class with @RequestMapping("/url").


HTTP request methods: GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS
@RequestMapping("/url") --> for all request methods.
@GetMapping("/url") -> @RequestMapping(value = "/url", method = RequestMethod.GET) -> for GET
req only
@PostMapping("/url") -> @RequestMapping(value = "/url", method = RequestMethod.POST) -> for
POST req only
@PutMapping("/url") -> @RequestMapping(value = "/url", method = RequestMethod.PUT) -> for PUT
req only
@DeleteMapping("/url") -> @RequestMapping(value = "/url", method = RequestMethod.DELETE) ->
for DELETE req only
Currently request handler method generates HTML output.
@RequestMapping(produces = "application/json", ...) --> Internally --> resp.setContentType(...);

Flexible signatures

https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html (17.3.3)

@RequestMapping("/welcome") // client request for url /welcome


public String home(Model model) {
model.addAttribute("curTime", new Date());
return "index"; // index is view name returned to front controller
}

OR

@RequestMapping("/welcome") // client request for url /welcome


public ModelAndView home() {
ModelAndView mav = new ModelAndView("index", "curTime", new Date());
return mav;
}

1/9
day13.md 11/27/2021

using HTML tags

mvctutorial1 (Spring MVC with HTML controls)

New -- Spring Starter Project


Fill project details
Spring Starter Dependencies
JDBC API
MySQL
Dev Tools
Spring Web
Finish
In pom.xml add dependencies for JSP & JSTL.

<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>

In application.properties add following properties

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
}

Create folder structure for JSP pages "webapp/WEB-INF/jsp" under src/main.

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

Create webapp/WEB-INF/jsp/failed.jsp to display invalid login message.


Create webapp/WEB-INF/jsp/manage.jsp to display "Hello, Admin" message.
Create webapp/WEB-INF/jsp/topics.jsp to display "Hello, Customer" message.
Browser: http://localhost:8080/login and "Sign In" with email & password.

Spring Form Tags

Spring can work with HTML tags.


For advanced features like validation, localization you should use spring form tags.
Refer slides for general steps to use Spring form tags.
1. Add <%@ taglib ... %>
2. <sf:form modelAttribute="..." ...>
3. <sf:input path="fieldName" ...>
Note that Spring form tags must be used in context with Spring form backing bean i.e. modelAttribute.
Spring form default modelAttribute name is "command".

mvctutorial2 (Spring MVC with Spring tags)

Copy mvctutorial1 as new project mvctutorial2. Rename name & artifactId into pom.xml and update the
Maven project.

Replace UserControllerImpl.login() method with following method:

@RequestMapping("/login")
public String login(Model model) {
Credentials cred = new Credentials("guest@gmail.com", "");
model.addAttribute("command", cred);
return "login";
}

Use appropriate spring tags into login.jsp.

<%@ page language="java" contentType="text/html; charset=UTF-8"


pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h3>Online Tutorials</h3>
<sf:form action="validate" method="post">
<table>
<tr>
<td>User Name: </td>

4/9
day13.md 11/27/2021

<td><sf:input path="email" /></td>


</tr>
<tr>
<td>Password: </td>
<td><sf:password path="password" /></td>
</tr>
<tr>
<td><input type="submit" value="Sign In" /></td>
</tr>
</table>
</sf:form>
</body>
</html>

In UserControllerImpl class replace validate() method.

@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 another controller class com.sunbeam.controllers.TutorialControllerImpl for Tutorial related


operations.

Create a POJO class for TopicSelection. It has single member int "topic".

In TutorialControllerImpl add method topics() to display all topicList.

@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";
}

In topics.jsp page use spring tags to display the topics.

5/9
day13.md 11/27/2021

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Topics</title>
</head>
<body>
<sf:form method="post" action="topictuts">
<sf:radiobuttons path="topic" items="${topicList}" itemLabel="name"
itemValue="id" delimiter="<br/>"/>
<br/><br/>
<input type="submit" value="Submit"/>
</sf:form>
</body>
</html>

Add method topicTutorials() into TutorialControllerImpl

@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.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Topic Tutorials</title>
</head>
<body>
<h2>Topic Tutorials</h2>
<c:forEach var="tut" items="${tutorialList}">
<a href="details?id=${tut.id}">${tut.name} (${tut.visits})</a> <br/>
<br/>
</c:forEach>

6/9
day13.md 11/27/2021

</body>
</html>

Add method details() in TutorialControllerImpl.

@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.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Details</title>
</head>
<body>
Hello, ${user.name} <hr/>

<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>

Add method logout() in UserControllerImpl.

@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.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Logout</title>
</head>
<body>
Thank you for using our services. <br/><br/>
<a href="/login">Login Again</a>
</body>
</html>

Assignment -- Admin part

Add @RequestMapping("/manage") manage() to get list of of tutorials and send to tutorials.jsp.


Create manage.jsp to display all tutorials in tabular format.
In manage.jsp add "Delete" action for each tutorial.
<a href='delete?id=${t.id}'>Delete</a>
Add @RequestMapping("/delete") delete() to delete the tutorial and return back to "redirect:manage".
In manage.jsp add "Edit" action for each tutorial.
<a href='edit?id=${t.id}'>Edit</a>
Add @GetMapping("/edit") edit() to find the tutorial of given id and send it to edit.jsp.
Create edit.jsp to display tutorial details in an Spring form (use textboxes and Submit) with
action="edit".
Add @PostMapping("/edit") edit() to update the details. Note that you need to implement
corresponding methods in TutorialServiceImpl and TutorialDaoImpl. At tne end return back to
"redirect:manage".

Request Handler Method Return Value -- String

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.

mvctutorial2 (State Management)

In UserControllerImpl(), validate() method add validated user into HttpSession.

8/9
day13.md 11/27/2021

In topics.jsp, topictutorials.jsp and details.jsp add Hello message. Hello, ${user.name}

9/9
day14.md 11/28/2021

Java EE
Agenda
State management
Assignment discussion
Validations
Static resources
Localization & Internationalization
REST or Hibernate

State Management (Traditional)

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

State management using SessionScope beans

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";
}

In topics(), topicTutorials() and details() method of TutorialControllerImpl add line.

model.addAttribute("uname", authUser.getName());

In topics.jsp, topictutorials.jsp, and details.jsp modify Hello message as

Hello, ${uname}

In details() method of TutorialControllerImpl add line.

model.addAttribute("role", authUser.getRole());

In details.jsp add links based on role.

<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

Client side 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, ...).

Server side Validations

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).

mvctutorial5 (Spring Validations)

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>

In model/pojo Credentials class use appropriate validation annotations.


In request handler method -- UserControllerImpl.validate()
The command/model object should be marked as @Valid and @ModelAttribute("...").

3/4
day14.md 11/28/2021

Immediate next argument must be BindingResult to collect validation errors.


Check BindingResult object to see errors -- hasErrors(). Send user to current view if error is found.
In login.jsp add <sf:errors> tags to display the error messages for email and password.
Run application and check if validations are working.

Database level Validations

Database level Validations can be done using CHECK constraints.

mvctutorial5 (Static Resources)

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: ...

Internationalization and Localization

Refer slides for concepts.

mvctutorial5 (Spring Localization)

Create file messages.properties under resources directory.


In application.properties add "spring.messages.basename=messages". This optional because default
name is messages.
In login.jsp file display all labels from this file using <s:message>.
Run application and check if default messages are visible (from messages.properties).
Create files messages_hi.properties, messages_mr.properties and messages_en.properties as discussed
in class.
Use translator to get corresponding messages.
Copy them directly into eclipse. Eclipse will convert it into UTF-8 format. (You may use native to
ascii converter online).
In login.jsp add

<%@ page contentType="text/html; charset=UTF-8" %>

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

Not part of Spring IO platform


Templating engine
Request and response
Client ----> Controller ----> View ----> Template Engine - Render ----> Response ----> Client
<html xmlns:th="http://www.thymeleaf.org">
<p th:text="'Hello World'"/>
'single quotes' for string constants
Eclipse Marketplace - Thymeleaf plugin (optional)

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

Spring MVC Thymeleaf - Hello World!

step 1: Create new spring starter project with following dependencies:

<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>

step 2: Add HomeController (under src/main/java - current package)

@Controller
public class HomeController {
@RequestMapping("/index") // url --> handlerMapping
public String index(Model model) {
model.addAttribute("curTime", new Date().toString());
return "home"; // view name --> viewResolver
}
}

step 3: Create thymeleaf template (under src/main/resources/templates - home.html)

<!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>

step 4: Run As - Spring Boot application

step 5: In browser - http://localhost:8080/index

Spring Web Application Deployment

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

C-DAC course end project

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

Option 3: React Frontend + Express


DMC Course
Option 1: React Frontend + Express + Mobile App (Android or iOS)
Option 2: React Frontend + Spring REST Backend + Mobile App (Android or iOS)4

ORM -- Object Relational Mapping

RDBMS <---> JDBC <---> Java


RDBMS --> Table + Rows + Columns
Java --> Class + Objects + Fields
JDBC Programming
SELECT query (executeQuery())
ResultSet --> POJO object (using Spring -- RowMapper)
INSERT query (executeUpdate())
Statement <-- POJO object
UPDATE query (executeUpdate())
Statement <-- POJO object
DELETE query (executeUpdate())
Statement <-- id

Thymeleaf config

ViewResolver configuration is "by default" in Spring Boot. Can be overridden as follows:

@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

Annotation based - ORM

@Entity

@Table --> ClassName -> TableName

If ClassName is same as TableName, then this is optional.

@Column --> FieldName -> ColumnName

@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.

private DataType fieldName;

Every field written in @Entity class is treated as column in database table.

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

private String author;


private String subject;
private double price;
@Transient // column is not present in table
private double gst;
// getter/setter -- follow java naming conventions
}

@Temporal will convert RDBMS Date Time types into java.util.Date, java.util.Calendar,
java.util.LocalDate, java.util.LocalTime, etc.

MySQL DATE --> @Temporal(TemporalType.DATE)


MySQL TIME --> @Temporal(TemporalType.TIME)
MySQL DATETIME --> @Temporal(TemporalType.TIMESTAMP) // DATE + TIME
MySQL TIMESTAMP --> @Temporal(TemporalType.TIMESTAMP) // DATE + TIME

@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;
}

@Column, @Id, @Temporal, @Transient are written on fields or getter methods.

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.

Demo 10 (Hibernate CRUD operations)

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

Bootstrapping --> Getting Started --> SessionFactory creation.

Demo 11 (Hibernate CRUD operations)

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

Advanced Java - Spring Boot


Agenda
Exception handling
File Upload & Download
Spring REST Client
Spring AOP
Spring Security

REST web services

REST stands for REpresentation State Transfer.


Object characteristics: State, Behaviour & Identity
State: Values of data members/fields.
Object state can be transferred (from server to client & vice-versa) in any format like JSON or
XML.
It is a Protocol to invoke web services from any client (with internet connection).
Client can use any platform/language.
REST is lightweight (than SOAP).
REST works on top of HTTP protocol.
It uses HTTP protocol request methods.
GET: to get records
POST: to create new record
PUT: to update existing record
DELETE: to delete record
REST services are stateless.
Each REST request is independent of another.
Request should include all required inputs and produce expected output.

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

JSON is Java Script Object Notation.


It is set of key-value pairs and supports few data types like numeric, string, boolean, null, array and
objects.

{
"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"
}
]
}

REST request/response formats

Variety of request and response formats are followed in industry.


JSON API: https://jsonapi.org/
JSend: https://github.com/omniti-labs/jsend
OData JSON: https://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os/odata-json-
format-v4.0-errata02-os-complete.html
HAL: https://stateless.group/hal_specification.html

REST request/response model

GET: http://localhost:8080/books
Request body: Empty

2 / 20
day19.md 12/25/2021

Response body: List of Books - 200

[
{ "_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

{ "_id": ..., "name": "...", "author": "...", "subject": "...",


"price": ... }

POST: http://localhost:8080/books
Request body:

{ "_id": ..., "name": "...", "author": "...", "subject": "...",


"price": ... }

Response body: 200


PUT: http://localhost:8080/books/1
Request body

{ "_id": ..., "name": "...", "author": "...", "subject": "...",


"price": ... }

Response body: 200


DELETE: http://localhost:8080/books/1
Request body
Response body: 200

Spring Boot REST services

Spring REST is subset of Spring Web MVC.


Spring boot auto-configures WebMvc and messageConverters automatically.
REST request handlers are implemented similar to web mvc request handlers.
Implemented using @Controller
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping or @RequestMapping
3 / 20
day19.md 12/25/2021

@RequestBody, @ResponseBody / ResponseEntity<>


@PathVariable, @RequestParam
Can be implemented using @RestController
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping or @RequestMapping
@RequestBody, ResponseEntity<>
@PathVariable, @RequestParam

Spring REST

Spring RestTemplate client

RestTemplate is used to create applications that consume RESTful Web Services. The application can be
console application, web application or another REST service.

RestTemplate can be created directly OR using RestTemplateBuilder.

@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

RestTemplate is make GET, POST, PUT or DELETE request to the resource.

Important RestTemplate methods

T getForObject(String url, Class<T> responseType, Object... uriVariables);

ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object...


uriVariables);

T postForObject(String url, Object request, Class<T> responseType, Object...


uriVariables);

ResponseEntity<T> postForEntity(String url, Object request, Class<T>


responseType, Object... uriVariables);

void put(String url, Object request, Object... uriVariables);

void delete(String url, Object... uriVariables);

4 / 20
day19.md 12/25/2021

ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?>


requestEntity, Class<T> responseType);

ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?>


requestEntity, ParameterizedTypeReference<T> responseType, Object...
uriVariables);

ResponseEntity<T> exchange(RequestEntity<?> entity, Class<T> responseType);

UriComponentsBuilder can be used to build Uri as per following steps.

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).

RequestEntity<MyRequest> request = RequestEntity


.post("https://example.com/{foo}", "bar")
.accept(MediaType.APPLICATION_JSON)
.body(reqBodyObject);
ResponseEntity<MyResponse> response = template.exchange(request,
MyResponse.class);

Spring REST services

Spring REST is subset of Spring Web MVC.


Spring boot auto-configures WebMvc and messageConverters automatically.
REST request handlers are implemented similar to web mvc request handlers.
Can be implemented using @RestController
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping or @RequestMapping
@RequestBody, ResponseEntity<>
@PathVariable, @RequestParam

Customizining JSON response fields

Request and Response body is converted into JSON using MappingJackson2HttpMessageConverter.


By default all fields of returned object are converted into JSON format.
5 / 20
day19.md 12/25/2021

Jackson annotations can be used to manipulate the response fields.


@JsonInclude(Include.NON_NULL): Include only non-null members.
@JsonInclude can be used on response object, individual fields or handler methods.
@JsonIgnore: Ignore the field in JSON response.
@JsonProperty("jsonFieldName"): Rename field in the JSON response.
@JsonManagedReference and @JsonBackReference are used to display objects with parent-child
relation and ensure that JSON response generation is not recursive.
@JsonManagedReference refers parent object, while @JsonBackReference refers child
object.

@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

Rest controllers can return entity objects directly.


However standard practices suggest not mixing data layer with frontend layer.
DTO classes are used to send/retrieve data from frontend.
They should be designed as per client application requirement.
Programmer can use @JsonProperty, @JsonIgnore, etc jackson annotations to control produced json
(on DTO classes).
Conversion from entity to DTO can be done in one of the following ways
Use DTO constructor.
Use static helper methods like fromEntity() and toEntity() or implement custom converter classes
for the same.

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

REST/MVC Exception Handling

If exception is raised in @RestController/@Controller request handler method, it can be handled in


various ways.
Catch exception & produce response
@ExceptionHandler at controller level
Global @ExceptionHandler into @ControllerAdvice

Catch exception & produce response

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);
}
}

@ExceptionHandler at controller level

It is advised to separate business logic and error handling logic.

Error handling logic can be implemented in a separate method in the controller annotated with
@ExceptionHandler.

Creating custom exception class enable exception handling more readable.

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);
}

Global @ExceptionHandler into @ControllerAdvice

If exception handling logic is common across multiple controllers, @ExceptionHandler can be


implemented globally in another class annotated with @ControllerAdvice.

@ControllerAdvice classes are auto detected by spring container.

@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);
}
// ...
}

Invoke REST services from JS

Use Postman to explore client code for various languages/libraries.


JavaScript - XHR

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

GET /resources/public-data/ HTTP/1.1


Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0)
Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example

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

In response, the server returns a Access-Control-Allow-Origin header with Access-Control-Allow-


Origin: * which means that the resource can be accessed by any origin.

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 is a programming paradigm/methodology.


Implements cross-cutting concerns without modifying core business logic.
Pre-processing & Post-processing
In Java EE, it is implemented using Filters (javax.servlet.Filter).
In Java, it can be implemented using Java Proxies or using Aspect/J framework.
Spring AOP is wrapper on Aspect/J library.

AOP Terminologies

Aspect

Implementation of cross-cutting concern(s).


In Spring AOP, it is a class containing cross-cutting concern implementation - @Aspect.
It will contain implementation of one or more advices implementations.

Advice

Implementation of a pre-processing or post-processing or both.


In Spring AOP, it is a method in @Aspect class.
Advice types: @Before, @Around, @AfterReturning, @AfterThrowing, @After.
@Before: Pre-processing -- before business logic
@AfterReturning: Post-processing -- after successful execution of business logic
@AfterThrowing: Post-processing -- after failure of business logic
@After: Post-processing -- after execution of business logic (like finally)
@Around: Pre-processing and Post-processing -- before and after execution of business logic

JoinPoint

Point of intersection where advice is applied.


In Spring AOP, it is an object containing information about the method on which advice is applied and
the object on which that method is invoked.
It is argument to the advice methods i.e. JoinPoint or ProceedingJoinPoint.

Pointcut

A predicate that matches join points.


Advice is associated with a pointcut expression and runs at any join point matched by the pointcut.
Can be used to combine multiple JoinPoints.

10 / 20
day19.md 12/25/2021

Target

The object on which business logic method is invoked.


Also called as advised object.

Proxy

The wrapper on the target object created by AOP framework.


Responsible for executing advices & actual business logic.
Proxy can be interface based (Dynamic proxy) or cglib.

Spring Boot AOP

Spring Boot DI enables auto-detection of @Aspect classes.


AopAutoConfiguration auto-configure AOP and need not to use @EnableAspectJAutoProxy explicitly.

Spring Boot AOP (demo12)

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>

step 3: Throw exception from AccountImpl.withdraw() method in case of insufficient balance.

// 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;
}

step 4: Implement @Aspect AccountAspectImpl class. Mark it as @Component.

@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

System.out.println("Before Deposit: Rs. " + jpt.getArgs()[0] + ",


Balance = " + acc.getBalance());
}

@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());
}

@Pointcut("execution (* Account.deposit(..)) || execution (*


Account.withdraw(..))")
public void accTransaction() {
}

@AfterReturning("accTransaction()")
public void afterTransaction(JoinPoint jpt) {
System.out.println("Sending Email on Transaction: " +
jpt.getSignature());
}
}

step 5: Ensure that "acc" @Bean is created in @Configuration BankConfig.

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().

Account acc = (Account) context.getBean("acc");


acc.setType("Current");

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

Security is essential part of any application.


Web MVC application
REST services
Micro-services
Spring security enables application level security.
Username/password authentication
Single-Sign-on SSO (Facebook, Google, Okta, etc).
Role based security (in application)
OAuth - Application authorization with another application
Micro-services security (JWT)
Method level security
Spring security is separate spring project.
Not part of Spring core framework.
Not part of Spring boot.
Spring security has separate release cycle.
Spring Boot provides auto-configuration for Spring security.

Spring security terminologies

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

Spring Security in web MVC

Spring security is based on "set" of Java EE filters called springSecurityFilterChain.

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.

In Spring boot application spring security is auto-configured when added on classpath.

Default behaviour of Spring security

Add authentication to URLs (except /error)


Add default login form
Create default user (name: user) and password (on console).
Handles login error
Store principal in HttpSession upon success
Logout on /logout URL

Spring security is very flexible with little configuration options.

Step 1: Create Spring Boot application with Web, Thymeleaf and Security starter.

Step 2: Create HomeController and index.html for mapping /.

Step 3: Test application with default user and password.

Step 4: Add additional pages and mappings.

Set fixed username/password

In application.properties

spring.security.user.name=sunbeam
spring.security.user.password=infotech

These credentials will be used instead of user/password-on-console.


Step 5: Test application with given user and password.

Username/Password Authentication

AuthenticationManager:

Responsible for user authentication -- authenticate() method -- returns Authentication object.


Internally manages/uses AuthenticationProvider.
Built using AuthenticationManagerBuilder.

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:

Follow builder design pattern to build AuthenticationManager.


inMemoryAuthentication()
jdbcAuthentication()
ldapAuthentication()

AuthenticationProvider:

AuthenticationManager delegates the fetching of persistent user information to one or more


AuthenticationProviders.
Available AuthenticationProvider implementations:
DaoAuthenticationProvider
OpenIDAuthenticationProvider
LdapAuthenticationProvider
...
If supports() given Authentication object type, then authenticate() it.
Responsible for user authentication -- authenticate() method -- returns Authentication object.
Input: Authentication object (hold credentials)
Output: Authentication object (hold principal)
Typically clears credentials after authentication.

UserDetailsService:

AuthenticationProvider use UserDetailsService service to load the user details.


UserDetails loadUserByUsername(java.lang.String username);
Available implementations are:
InMemoryUserDetailsManager
JdbcDaoImpl
LdapUserDetailsManager
...

16 / 20
day19.md 12/25/2021

UserDetails:

UserDetailsService returns UserDetails for given username.


It hold details like username, password, authorities, enabled, etc.
Available implementations are:
User
LdapUserDetailsImpl
...

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.

Step 3: Implement SecurityConfig class inherited from WebSecurityConfigurerAdapter.

Add @EnableWebSecurity on the class.


Override void configure(AuthenticationManagerBuilder auth) to set up InMemoryAuthentication.
Provide a NoOpPasswordEncoder bean.

Step 4: Test application with configured user and password.

Authorization

HttpSecurity:

Configures security using builder design pattern.


Allow URL for given role/user.
Using antMatchers.
Configure CSRF (Cross-Site Request Forgery).
CSRF is an attack that forces an end user to execute unwanted actions on a web
application in which they are currently authenticated.
Configure CORS (Cross-Site Resource Sharing).
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a
web page to be requested from another domain outside the domain from which the first
resource was served.

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.

Step 3: Implement SecurityConfig class inherited from WebSecurityConfigurerAdapter.

Add @EnableWebSecurity on the class.


Override void configure(AuthenticationManagerBuilder auth) to set up InMemoryAuthentication.
Provide a NoOpPasswordEncoder bean.

Step 4: Override void configure(HttpSecurity http) to set up Authorization in SecurityConfig.

Allow / for all users.


Allow /user only for ROLE_USER.

17 / 20
day19.md 12/25/2021

Allow /admin only for ROLE_ADMIN.

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.

Spring Data JPA Authentication (security5)

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

Step 10: Override void configure(AuthenticationManagerBuilder auth) to set up JdbcAuthentication.


Attach userDetailsService().
Step 11: Test application with user and password (given in data.sql) of different roles.

JWT (JSON Web Token)

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.

Authorization using JWT

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

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 JwtUtil class for JWT common operations like generateToken() and validateToken().
Step 9: Create @RestController AuthController to authenticate user with POST request (having email &
password in body) and generate JWT token if user is valid. Use AuthenticationManager (@Autowired)
to authenticate user.
Step 10: Implement SecurityConfig class inherited from WebSecurityConfigurerAdapter.
Add @EnableWebSecurity on the class.
Provide a BCryptPasswordEncoder bean.
Step 11: Override void configure(HttpSecurity http) to set up Authorization in SecurityConfig.
Allow / and /authenticate for all users.
Allow /user only for ROLE_USER.
Allow /admin only for ROLE_ADMIN.
Step 12: Override void configure(AuthenticationManagerBuilder auth) to set up JdbcAuthentication.
Attach userDetailsService().
Step 13: Create authenticationManager bean in SecurityConfig - to autowire in AuthController.
Step 14: Test /authenticate endpoint with postman. Json body include email and password.
Ensure that generated response contains valid payload (using jwt.io).
Step 15: Test /user or /admin endpoint by adding JWT token into Authorization header with Bearer
prefix. It will not work.
Step 16: Create JwtRequestFilter inherited from OncePerRequestFilter. Mark @Component for DI. In its
doFilterInternal() method.
Check if appropriate "Authorization" header is available (with prefix Bearer).
Get the token from the header value (by stripping Bearer prefix).
Retrieve token and check if it is valid (not expired).
If valid JWT token, create and attach an Authentication token to current SecurityContext (if no
Authentication already set).
Execute the next filter in the chain.
Step 17. Modify Authorization settings in SecurityConfig's void configure(HttpSecurity http).
Ensure that there is no HttpSession created, by setting SessionCreationStrategy as STATELESS.
Add jwtRequestFilter before UsernamePasswordAuthenticationFilter in spring security filter chain.
Step 18: Test application with user and password (given in data.sql) of different roles.
First make request to /authenticate to get JWT token.
Use JWT token in Authorization header of request to /user and /admin.

20 / 20

You might also like