0% found this document useful (0 votes)
2 views

AJ notes

The document provides an overview of Java Generics, including the concepts of generic types, parameterized types, and wildcards, which enhance code safety and reusability. It also covers the Java Collection Framework, detailing various data structures such as Lists, Sets, Queues, and Maps, along with their characteristics and common operations. Additionally, it introduces lambda expressions and JSP architecture, explaining their components and lifecycle processes.

Uploaded by

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

AJ notes

The document provides an overview of Java Generics, including the concepts of generic types, parameterized types, and wildcards, which enhance code safety and reusability. It also covers the Java Collection Framework, detailing various data structures such as Lists, Sets, Queues, and Maps, along with their characteristics and common operations. Additionally, it introduces lambda expressions and JSP architecture, explaining their components and lifecycle processes.

Uploaded by

fannyskylark2003
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 43

Module 1

Introduction to Generics :
What are Generics?
Generics are a way to create classes, interfaces, and methods with type
parameters. Think of them as a way to handle data of any type without
needing to specify the exact type when you create your code.

Why use Generics?


They make code safer and reusable by ensuring that only compatible
types are used. For example, a generic List<String> ensures all items are
strings, catching type errors at compile-time.

Generic Types and Parameterized Types

 Generic Types: These are types that work with any data type, like
List<T> where T is a placeholder for the type you specify later.
 Parameterized Types: When you specify the type for a generic,
like List<String>, you're creating a parameterized type. Here,
String is the parameter, and List<String> is a list that only holds
strings.
 Example: If you have a class Box<T>, it can store any type. Using
Box<Integer> means that T is replaced by Integer.

Introduction to WildCards
In Java Generics, wildcards are used to represent unknown types. They
allow you to write more flexible code that can work with different types,
especially when working with generics. Wildcards are represented by the
question mark ? and are mainly used in method arguments to define what
kind of types the method will accept.

There are three types of wildcards:


 Unbound WildCard <?>
 UpperBound WildCard <? extends Type>
 LowerBound WildCard <? super Type>
Unbounded Wildcard (<?>)

 Represents an unknown type.


 Used when you don’t know the type or when the type is not
important.
 Useful for methods that operate on collections of objects in a read-
only fashion.

Upper Bounded Wildcard (<? extends Type>)

 Represents an unknown type that is a subclass of a specified type.


 Used to read data from a generic object, ensuring that it is of a
certain type or subtype.

Example :

import java.util.ArrayList;

public class UpperBound {

public static void main(String[] args){

ArrayList<Integer> intList= new ArrayList<>();

intList.add(9);

ArrayList<String> strList= new ArrayList<>();

strList.add("String");

ArrayList<Double> dblList= new ArrayList<>();

dblList.add(9.0);

//Works

print(intList);

print(dblList);

//Gets error (because String doesn’t extends Number class)

print(strList);
}

public static void print(ArrayList<? extends Number> list){

System.out.println(list);

Lower Bounded Wildcard (<? super Type>)

 Represents an unknown type that is a superclass of a specified


type.
 Used to write data to a generic object, ensuring that it can accept a
specific type or any of its superclasses.

public class Animals{

public static void main(String[] args){

ArrayList<Integer> intList= new ArrayList<>();

intList.add(9);

ArrayList<Double> dblList= new ArrayList<>();

dblList.add(9.0);

ArrayList<Number> nList= new ArrayList<>();

nList.add(9);

ArrayList<Object> oList= new ArrayList<>();

oList.add("snasj");

//Works (Because they are super class of Number Class)

print(nList);

print(oList);
//Gets error (because Double is not a super class of Number class)

// print(dblList);

public static void print(ArrayList<? super Number> list){

System.out.println(list);

Java Collection Framework :

The Java Collection Framework provides a set of classes and interfaces


that implement commonly used data structures, such as lists, sets, and
maps. It simplifies the manipulation of data and provides a high-level API
for storing and processing groups of objects.

Basic Operations in Collections :

Basic operations are those that perform common tasks such as adding,
removing, and checking elements. Most of these operations are defined in
the Collection interface, which is the root interface of the Collection
Framework.

 Adding elements:

A] add(E e): Adds an element e to the collection. Returns true if the


collection changed as a result.
B] addAll(Collection<? extends E> c): Adds all elements from another
collection to this collection.

 Removing elements:

A] remove(Object o): Removes a single occurrence of the specified


element from the collection.
B] removeAll(Collection<?> c): Removes all elements in the specified
collection from this collection.

 Checking for elements:

A] contains(Object o): Returns true if the collection contains the specified


element.
B] containsAll(Collection<?> c): Returns true if the collection contains
all elements in the specified collection.

 Size of Collection:

size(): Returns the number of elements in the collection.

 Clearing the collection:

clear(): Removes all elements from the collection.

2. Bulk Operations

Bulk operations work with multiple elements at once, often to perform


batch processing.

addAll(Collection<? extends E> c): Adds all elements from the specified
collection.

removeAll(Collection<?> c): Removes all elements from the collection


that are also in the specified collection.

retainAll(Collection<?> c): Retains only the elements that are also


contained in the specified collection.

containsAll(Collection<?> c): Returns true if the collection contains all


elements of the specified collection.

isEmpty(): Checks if the collection is empty.


3. Iteration

To iterate through the elements of a collection, Java provides several


ways:

 For-each loop: Simplified iteration introduced in Java 5.

for (String item : collection) {


System.out.println(item);
}

 Iterator: A more flexible way of iterating, allowing removal during


iteration.

Iterator<String> iterator = collection.iterator();


while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}

1. List :

A List is an ordered collection that allows duplicate elements and


provides indexed access to its elements.

Characteristics:
Ordered: Maintains the order of elements as they were inserted.
Allows Duplicates: Elements can appear multiple times in a list.
Indexed Access: Elements can be accessed using an index, like an array.

Common Implementations:
ArrayList: Backed by a dynamic array; efficient for random access but
slower for insertions and deletions in the middle.
LinkedList: Backed by a doubly linked list; efficient for insertions and
deletions but slower for random access.
Vector (legacy): Synchronized version of ArrayList, mainly used in
legacy code.

Use Cases:
Ideal when you need to maintain the order of elements.
Suitable when you need to access elements by index frequently.
Commonly used for caching, ordered data processing, and to-do lists
where duplicates are allowed.

Example:
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Apple"); // Duplicates are allowed
System.out.println(list); // Output: [Apple, Banana, Apple]

2. Set :
A Set is an unordered collection that does not allow duplicate elements.
It’s useful when you need to maintain a unique collection of items.

Characteristics:
Unordered (except for specific implementations).
No Duplicates Allowed: Ensures that each element is unique.

Common Implementations:
HashSet: Backed by a hash table; does not maintain order.
LinkedHashSet: Backed by a hash table and a linked list; maintains
insertion order.
TreeSet: Backed by a red-black tree; maintains elements in sorted order.

Use Cases:
Suitable for storing unique elements, such as IDs, usernames, or product
SKUs.
Useful for removing duplicates from a collection.
Can be used for set operations (like union, intersection, and difference).

Example:
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // Duplicate is ignored
System.out.println(set); // Output: [Apple, Banana]

3. Queue :

A Queue is a collection that follows the First-In-First-Out (FIFO)


principle. It’s often used for scenarios where the first element added
should be the first one removed, like handling tasks or requests in the
order they arrive.

Characteristics:
Follows FIFO ordering.
New elements are added at the end, and removal happens from the front.
Queue is an interface; common implementations include LinkedList and
PriorityQueue.

Common Methods:
offer(): Adds an element to the queue; returns false if the queue is full (in
bounded queues).
poll(): Removes and returns the head of the queue; returns null if the
queue is empty.
peek(): Retrieves, but does not remove, the head of the queue; returns null
if the queue is empty.

4. Map :

A Map is a collection that stores key-value pairs, where each key is


unique, and each key maps to one value.

Characteristics:
No Duplicate Keys: Each key can map to only one value.
Unordered (unless using specific implementations).

Common Implementations:
HashMap: Backed by a hash table; does not guarantee any order.
LinkedHashMap: Maintains insertion order of keys.
TreeMap: Backed by a red-black tree; maintains keys in sorted order.
ConcurrentHashMap: A thread-safe map for concurrent operations.

Use Cases:
Ideal for scenarios where you need to associate unique keys with values.
Used frequently for lookup tables, caches, and dictionaries where you
want to retrieve values based on unique keys.

Example:
java
Copy code
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Apple", 3); // Key "Apple" is updated
System.out.println(map); // Output: {Apple=3, Banana=2}

Q] Explain TreeMap and HashMap classes of collection


Framework.

Both TreeMap and HashMap are part of the Java Collection Framework
and are used to store key-value pairs. But they work differently.

TreeMap :

How It Works:
 A TreeMap organizes all the keys in sorted order (ascending by
default).

Key Rules:
 No null keys allowed (because sorting a null value doesn’t make
sense).
 Null values are allowed (you can store a null as a value, like key:
John, value: null).
Speed:
 Slightly slower because it spends time sorting the keys.
 Every operation (like adding, removing, or finding a key) takes O(log
n) time.

Extra Features:
 You can easily find the smallest or largest key (firstKey(), lastKey()).
 You can get keys in a specific range (e.g., all keys between A and M).

When to Use:
 When you need the keys to always stay sorted.
 Useful for tasks like leaderboards where you need data in a ranked
order.

example :
import java.util.TreeMap;

public class TreeMapExample {


public static void main(String[] args) {
TreeMap<String, Integer> scores = new TreeMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);

System.out.println("TreeMap (sorted): " + scores); // {Alice=90,


Bob=85, Charlie=95}
System.out.println("Top scorer: " + scores.lastKey()); // Charlie
}
}

HashMap :

How It Works:
 A HashMap uses a hashing technique to store data, which makes it
super fast for looking up or adding keys.
 There’s no specific order for keys.

Key Rules:
 Allows one null key (e.g., key: null, value: Something).
 Allows multiple null values (e.g., key1: X, value: null, key2: Y,
value: null).
Speed:
 Very fast! Adding, removing, or finding keys usually takes O(1) time
(constant time).
 Can get slower if too many keys “clash” (hash collisions), but this is
rare.

When to Use:
 When you just need quick access to key-value pairs.

Example :
import java.util.HashMap;

public class HashMapExample {


public static void main(String[] args) {
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put(null, 100); // Allows one null key

System.out.println("HashMap: " + scores); // {null=100, Alice=90,


Bob=85}
System.out.println("Score of Alice: " + scores.get("Alice")); // 90
}}

Lambda Expressions :

lambda expressions provide a simpler and more concise syntax for


writing anonymous classes that implement functional interfaces. While
traditional anonymous classes require a lot of boilerplate code, lambda
expressions allow you to achieve the same functionality with minimal
syntax.

A lambda expression consists of three main components:


 Parameters – A comma-separated list of formal parameters enclosed
in parentheses ().
 Arrow Token – The token ->, which separates parameters from the
body of the lambda.
 Body – The code that implements the function, which can be either a
single expression or a block of statements.

Syntax Example :
(parameters) -> expression
// or
(parameters) -> { statements; }

1. Lambda Type Inference :

Type Inference in lambda expressions allows the Java compiler to infer


parameter types based on the context in which the lambda is used. Since
lambda expressions work with functional interfaces, the compiler already
knows the expected parameter types from the interface’s method.

If the parameter types are unambiguous, they can be omitted. For


example, instead of (int x, int y) -> x + y, you can write (x, y) -> x + y.

2. Lambda Parameters

Lambda expressions can have zero or more parameters:

No Parameters: Use empty parentheses () if there are no parameters.


One Parameter: Parentheses can be omitted if there’s only one parameter,
for example, x -> x * x.
Multiple Parameters: Use parentheses to separate multiple parameters, for
example, (a, b) -> a + b.

3. Lambda Function Body :

The Function Body of a lambda can be:

A single expression: When the body is a single expression, the return


keyword is implicit, and no braces {} are needed.
A block of statements: If the body has multiple statements, braces {} are
required, and you must explicitly use return if you’re returning a value.
Module 2
Introduction Java EE Programming

JSP Architecture :

 JSP (JavaServer Pages) architecture follows a client-server model


where the client sends an HTTP request to the server. The server
contains a JSP engine that compiles the JSP into a servlet.
 The servlet processes the request and generates dynamic HTML,
which is sent back to the client as an HTTP response. The servlet
container (e.g., Tomcat) manages the JSP lifecycle, including
compilation, request handling, and session management.
 The lifecycle involves translation, initialization, request processing,
and destruction of the JSP-generated servlet.

Jsp Architecture block diagrams :


JSP lifecycle :

1. Translation/Compilation Phase :
 When a JSP page is requested for the first time, the JSP container
(like Apache Tomcat) converts the JSP file into a Java Servlet (which
is a Java program). This process is called "translation."
 The JSP code is turned into Java code that handles the logic and
dynamic content (like displaying different information based on user
input).
 Then, this Java code is turned into a bytecode file (.class file) that the
computer can understand and run.

2. Initialization Phase :
 After the JSP page has been converted into a servlet, the JSP
container loads this servlet into memory.
 The container calls a special method called init() to set things up for
the servlet. This step happens only once when the JSP page is first
requested.
 In the init() method, things like database connections or shared
resources are prepared.

3. Request Handling Phase :


 Once the servlet is ready, it can handle HTTP requests (like when the
user asks for a page).
 The servlet’s service() method is called to process the request.
 It takes the user's input (like form data), processes it, and then
generates a response (usually in HTML format).
 The generated response is then sent back to the user’s browser,
showing the results of the request.

4. Destroy Phase :
 When the servlet is no longer needed (like when the server is shutting
down or the JSP page is being replaced), the container calls the
destroy() method.
 In this step, the servlet releases resources it was using, like closing
database connections or cleaning up memory.
 After that, the servlet is removed from memory.
JSP Building blocks :

building blocks are the essential components that allow for the
development of dynamic web pages. These include elements like
directives, scripting elements, actions, and expressions, each serving
different purposes within JSP files.

1. Directives :

 Directives provide instructions to the JSP engine when the page is


compiled.
 They are used to define page settings, include external files, and
manage tag libraries.

There are three main types of directives in JSP:

1] Page Directive
2] Include Directive
3] Taglib Directive

1. Page Directive :

 The page directive defines attributes that apply to the entire JSP page.
 Syntax: <%@ page attribute="value" %>

Important attributes:

1] language: Specifies the scripting language used in the JSP. By default,


it’s java.
Example: <%@ page language="java" %>

2] import: Imports Java classes or entire packages, making them available


for use within the JSP. Multiple imports can be comma-separated.
Example: <%@ page import="java.util.*, java.io.*" %>

3] buffer: Defines the size of the buffer. Common values include none
(no buffering) or a specific size (e.g., 8kb).
Example: <%@ page buffer="16kb" %>

4] autoFlush: Determines whether the buffer should be flushed


automatically when it is full. If set to false, an exception is thrown when
the buffer is full.
Example: <%@ page autoFlush="true" %>
5] errorPage: Specifies a JSP page that will handle any uncaught
exceptions thrown by the current page. This page acts as an error handler.
Example: <%@ page errorPage="error.jsp" %>

6] isErrorPage: Indicates whether the current JSP page can act as an error
handler for other JSP pages.
Example: <%@ page isErrorPage="true" %>

2. Include Directive :

 The include directive allows content from another file to be statically


included in the JSP during the page translation phase. This is useful
for reusing headers, footers, or other shared components.
 Syntax: <%@ include file="relativeURL" %>

Important attribute:

file: Specifies the path to the file to be included.the included file's content
is added to the JSP page at translation time.
Example: <%@ include file="header.jsp" %>

3. Taglib Directive :

 The taglib directive allows for the use of custom tags defined in tag
libraries, such as the JSP Standard Tag Library (JSTL). This enables
modular and reusable code by allowing complex functionalities to be
handled by custom tags.
 Syntax: <%@ taglib prefix="prefix" uri="uri" %>

Important attributes:

prefix: Specifies a short name that will be used in the JSP to refer to the
custom tags from the library.
Example: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"
%>

uri: Defines the URI for locating the tag library descriptor (TLD) file,
which contains the tag definitions and attributes.
Example: <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"
%>
2. Scripting Elements

 Scripting elements allow you to embed Java code directly in a JSP


file.
 There are three types of scripting elements:
1] Declaration
2] Scriptlet
3] Expression

Declarations: Used to declare variables and methods that can be used


throughout the JSP page.
Syntax: <%! declaration; %>
Example: <%! int counter = 0; %>

Scriptlets: Allow Java code to be inserted into the service method of the
JSP page. Scriptlets are used to execute Java code that interacts with the
JSP content.
Syntax: <% code %>
Example: <% counter++; %>

Expressions: These are used to output values directly to the client.


Syntax: <%= expression %>
Example: <%= counter %>

3. Action tag

JSP action tags are XML-like tags that enable dynamic functionality
within a JSP page. These tags are processed by the server and used to
perform tasks such as including content from other resources, managing
JavaBeans, and forwarding requests. They are essential for creating
modular and reusable JSP code.
Here are the some JSP action tags :

1. <jsp:include> :
 The <jsp:include> action tag dynamically includes the output of
another resource (such as another JSP, HTML page, or servlet) at
request time.
 This is different from the include directive (<%@ include %>), which
includes content at translation time.

Syntax: <jsp:include page="relativeURL" />

Attributes:
page: Specifies the path to the resource to be included.
Example: <jsp:include page="header.jsp" />

Use Case: Commonly used to include headers, footers, or other reusable


content that may change dynamically, allowing for updates without
modifying the main JSP page.

2. <jsp:forward> :

The <jsp:forward> action tag forwards the request to another resource


(JSP, servlet, or HTML page) on the server.
Once the request is forwarded, the original JSP page stops processing.

Syntax: <jsp:forward page="relativeURL" />

Attributes:
page: Specifies the path to the target resource for the forward action.
Example: <jsp:forward page="login.jsp" />

Use Case: Frequently used in login pages, form submissions, and error
handling scenarios where, based on conditions, the request needs to be
forwarded to a different JSP or servlet.

3. <jsp:param> :

The <jsp:param> tag is used in conjunction with <jsp:include>,


<jsp:forward>, and <jsp:plugin> tags to pass parameters to the target
resource.

Syntax: <jsp:param name="paramName" value="paramValue" />


Attributes:
name: Specifies the name of the parameter.
Example: <jsp:param name="username" value="JohnDoe" />

value: Specifies the value of the parameter.


Example: <jsp:param name="userType" value="admin" />

Use Case: Used to pass additional information to an included or


forwarded JSP page, enabling parameter-based behavior in the target
page.

4. <jsp:useBean>

The <jsp:useBean> action tag creates or locates a JavaBean instance,


which can then be used to store and retrieve data within the JSP page.
It checks if a bean of the specified scope already exists; if not, it creates a
new one.

Syntax: <jsp:useBean id="beanId" class="fullyQualifiedClassName"


scope="scope" />

Attributes:

id: Specifies a unique identifier for the bean, used to reference it within
the JSP page.
Example: <jsp:useBean id="user" class="com.example.User" />
class: The fully qualified name of the JavaBean class.
Example: <jsp:useBean id="user" class="com.example.User" />
scope: Specifies the bean’s scope (page, request, session, or application),
determining its lifetime and visibility.
Example: <jsp:useBean id="user" class="com.example.User"
scope="session" />
Use Case: Commonly used to store user or session data, such as form
input, throughout multiple JSP pages, enabling data sharing across
different parts of an application.

JSP Implicit Objects :


In JavaServer Pages (JSP), implicit objects are pre-defined objects that
JSP provides to simplify web development. These objects are created by
the JSP container, making it easy to access request, response, session,
application, and other information without explicitly creating or
managing these objects in code.

1. request Object :
The request object represents the data sent by the client to the server.
It helps you access things like form inputs, query parameters in the URL,
headers, and cookies.
Examples of use:
getParameter("name"): Get values from form fields.
getAttribute("key"): Access temporary data stored during a single
request.
getSession(): Get the user’s session if they have one.
Scope: It’s only available during the current request (e.g., while loading a
page).
Ex. String username = request.getParameter("username");

2. response Object :
The response object represents the reply sent from the server back to the
client.
You can use it to set response details, like content type, add cookies, or
redirect to another page.
Examples of use:
setContentType("text/html"): Set the type of content being sent (e.g.,
HTML, JSON).
addCookie(new Cookie("name", "value")): Add a cookie for the user.
sendRedirect("newPage.jsp"): Redirects the client to another page.
Scope: Exists only while building the response for the client.
Cookie userCookie = new Cookie("username", "JohnDoe");
response.addCookie(userCookie);

3. session Object :
The session object stores user-specific data across multiple requests (like
pages) for a single user.
Use it to keep track of things like login status or preferences.
Examples of use:
getAttribute("key"): Get data from the session.
setAttribute("key", value): Store data for this user session.
invalidate(): End the session (e.g., when the user logs out).
Scope: Lasts as long as the user is active on the site or until they log out.
session.setAttribute("user", username);
String currentUser = (String) session.getAttribute("user")

4. application Object :
The application object stores data that is shared across the entire
application.
It’s useful for settings or data that should be accessible to all users.
Examples of use:
getAttribute("key"): Access global data for the application.
setAttribute("key", value): Save data that everyone can use.
Scope: Lasts as long as the application is running.
<%
visitCount = (Integer) application.getAttribute("visitCount");
if (visitCount == null) {
visitCount = 1;
}
else {
visitCount++;
}
application.setAttribute("visitCount", visitCount);
%>
<p>Total visits to this site: <%= visitCount %></p>

5. out Object :
The out object is used to send content directly to the client.
It’s like a writer that lets you print text or HTML to the page.
Examples of use:
print("Hello, World!"): Print text to the page.
println("Welcome!"): Print text with a newline.
Scope: Exists only while generating the response for the client.
out.print("<h1>Welcome to My Site!</h1>");

6. config Object :
The config object holds configuration information about the servlet (the
server-side program that powers JSP).
It’s useful for accessing parameters that were set when the servlet was
initialized.
Examples of use:
getServletName(): Get the name of the servlet.
getInitParameter("key"): Get a setting that was defined in the web.xml
file.
Scope: Available as long as the application is running; settings cannot be
changed after initialization.
<%
String appName = config.getInitParameter("applicationName");
%>
<p>Application Name: <%= appName %></p>

7. page Object :
The page object is a reference to the current JSP page itself.
Think of it as a shortcut to access methods on the page itself.
Scope: Limited to the current page and isn’t usually needed directly.
<%
// Using `page` is equivalent to using `this` in a JSP
String currentPageName = page.getClass().getName();
%>
<p>This JSP page's class name is: <%= currentPageName %></p>

8. pageContext Object :
The pageContext object provides access to all the different scopes (like
request, session, application) and other JSP objects.
It’s like a central tool for managing attributes and interacting with
request, response, and session data.
Examples of use:
setAttribute("key", value): Set an attribute for the current page.
getRequest(): Get the request object.
Scope: Limited to the current page.
pageContext.setAttribute("pageMessage", "This is a page-scoped
message.");

9. exception Object
The exception object is only available on error pages.
It represents any errors that occurred while processing a request.
Examples of use:
getMessage(): Get the error message.
printStackTrace(): Print the error details.
Scope: Only available on pages that are set up to handle errors (using
isErrorPage="true").
<%@ page isErrorPage="true" %>
<%
if (exception != null)
{ out.println("<p>Error: " + exception.getMessage() + "</p>");}
%>

Session Tracking types and methods :


When a user visits a website, the server doesn't automatically remember
who they are or what they did on previous pages because HTTP (the
protocol used for web pages) is stateless. This means that every time you
load a page, it's like starting fresh. Session tracking helps the server
"remember" things like who the user is and what actions they took, so
they don't have to start from scratch every time.

Here are the common ways JSP tracks sessions:

1. URL Rewriting :
 How it works: The server adds session information directly into the
URL when you click a link. This means the browser automatically
sends this session information when you visit the next page.
 When to use it: It's useful if the user's browser has cookies turned off,
because cookies won’t work in that case.
 Example: When you click a link like this:
<a href="<%= response.encodeURL("nextPage.jsp") %>">Go to next
page</a>
 The encodeURL method adds session information to the link's URL
so the server can still know who you are.

2. Hidden Form Fields :


 How it works: When you fill out a form and submit it, session
information can be stored in a hidden field that the user can’t see. The
server gets this session info when the form is submitted.
 When to use it: Useful when you're dealing with forms (like login
forms or payment details) and need to keep track of the user’s session
without showing any session data in the URL.
 Example:
<form action="nextPage.jsp" method="post">
<input type="hidden" name="sessionID" value="<%= session.getId()
%>">
<input type="submit" value="Submit">
</form>
 This hidden input field sends the session ID back to the server when
the form is submitted.

3. Cookies :
 How it works: Cookies are small pieces of data that are stored on the
user's computer. When you visit a site, the server sends a cookie with
a unique session ID, and the browser sends it back to the server each
time you visit a page.
 When to use it: This is the most common way of remembering users,
because it's easy to implement and widely supported by browsers.
 Example:
Cookie sessionCookie = new Cookie("JSESSIONID", session.getId());
response.addCookie(sessionCookie);
 This code creates a cookie with a session ID and sends it to the
browser, so it can be sent back with the next request.

4. HTTP Session API (Default Method)


 How it works: The HttpSession API is the easiest and most common
way of tracking sessions. It automatically creates a session for each
user when they first visit the website, and you can store and retrieve
data in that session.
 When to use it: This is usually the default choice for most JSP
applications because it works well and requires the least effort.
 Example:
HttpSession session = request.getSession();
session.setAttribute("username", "Shadow");
 Here, the getSession() method creates a session if it doesn't exist, and
the setAttribute() method stores the username in that session.

Q] Demonstrate the Custom Tags with example for


formatting date.
OR
Q] Imagine you are tasked with repeatedly formatting and
displaying dates in multiple sections of JSP application.
Create a reusable custom JSP tag <formatDate>, that will
display the date like “2024-11-11 10:15AM”.

Steps to Create and Use a Custom JSP Tag :


Define a Tag Handler Class :
-This class implements the logic for the custom tag.

Create a TLD (Tag Library Descriptor) File :


-This file maps the custom tag to the handler class.

Use the Custom Tag in JSP :


-Import the tag library in the JSP and use the tag.

example :

FormatDateTag.java :

package com.customtags;

import java.util.Date;

public class FormatDateTag extends SimpleTagSupport {


private Date date;

// Setter for the date attribute


public void setDate(Date date) {
this.date = date;
}

@Override
public void doTag() throws JspException, IOException {
if (date != null) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-
MM-dd HH:mm:ss");

String formattedDate = formatter.format(date);


getJspContext().getOut().write(formattedDate);
} else {
getJspContext().getOut().write("No date provided.");
}
}
}
customtags.tld :

<taglib>

<uri>customtags</uri>

<tag>
<name>formatDate</name>
<tag-class>com.customtags.FormatDateTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>date</name>
<required>true</required>
<type>java.util.Date</type>
</attribute>
</tag>
</taglib>

index.jsp :

<%@ taglib uri="http://customtags" prefix="ct" %>


<%@ page import="java.util.Date" %>

<!DOCTYPE html>
<html>
<head>
<title>Custom JSP Tag Example</title>
</head>
<body>
<h1>Formatted Date Example</h1>
<p>Current Date and Time: <ct:formatDate date="<%= new Date()
%>" /></p>
</body>
</html>
MODULE 3

Q] Explain Spring framework with suitable diagram ?

The Spring Framework is a popular, lightweight, and powerful


framework for building Java-based applications. It provides tools and
features to simplify the development of enterprise-level applications,
making it easier to build, test, and deploy robust software.

1. Data Access / Integration :


This part helps you work with databases and other systems that store or
exchange data:
JDBC: Makes it easier to connect to and work with a database by
managing things like resources and queries for you.
ORM: Works with tools like Hibernate to let you handle databases using
objects instead of writing SQL queries.
OXM: Converts data between objects in your app and XML format.
JMS: Helps send and receive messages between different parts of your
app, making them communicate in real-time.
Transactions: Ensures the consistency of data when performing multiple
actions, such as saving or updating data.

2. Web (MVC / Remoting) :


This part is used to create web applications and manage communication
between users (clients) and the server:

WebSocket: Enables live, real-time updates like chat applications or


notifications.
Servlet: Helps handle user requests (e.g., opening a webpage) and send
responses (e.g., displaying the webpage).
Web: Supports building websites using Spring MVC, a structure that
organizes your code

3. AOP (Aspect-Oriented Programming) :


This part is for handling tasks that affect the whole application, such as
logging, security, or transaction management:

Aspects: These are the parts of your app that handle tasks like logging or
security.
Instrumentation: Tools to modify and manage your code while it is
running.

4. Messaging :
This part helps your app send and receive messages, like notifications or
updates, using tools like RabbitMQ or Kafka.

5. Core Container :
This is the foundation of the Spring Framework. It manages objects
(called beans) and how they interact:

Beans: These are the building blocks of your app, and Spring manages
their lifecycle and settings.
Core: Provides basic features like managing the relationships between
objects (dependency injection).
Context: Works with the Core to manage your app as a whole and
provides tools to use beans more easily.
SpEL: A simple way to include dynamic logic in your app’s configuration,
like calculations or conditions.

6. Test :
This part helps you test your app to ensure it works correctly:

Works with popular testing tools like JUnit and TestNG.


Makes it easier to test individual parts of your app (unit testing) and how
they work together (integration testing).

Q] Explain a POJO class.

What is a POJO?
 POJO stands for Plain Old Java Object.
 It’s a basic Java class that contains variables (fields) and methods to
access or modify them (getters and setters).
 POJOs are used to define objects in a simple and readable way.

POJO vs. JavaBeans :


 Similarities: Both are used to define objects to improve readability
and reusability.
 Difference:
 JavaBeans have some restrictions (e.g., they must implement
Serializable, follow specific naming conventions, etc.).
 POJOs do not have restrictions. They are more flexible and can be as
simple as needed.

What Makes a POJO Special?


 No Restrictions:
 Does not need to implement interfaces.
 Does not need to extend specific classes.
 Does not require annotations or specific design patterns.
 Flexibility: POJOs are easy to write and use.
How to Create a POJO Class?

 A POJO class generally:


 Has private variables (fields) for data storage.
 Has getters and setters to read and update the variable values.
 Is public, so it can be accessed by other parts of the program.
 May have constructors to initialize objects (optional).

Example: Employee.java

// POJO class example


package Jtp.PojoDemo;

public class Employee {


private String name; // private variable
private String id;
private double sal;

// Getter and Setter for name


public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

// Getter and Setter for id


public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

// Getter and Setter for salary


public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
}

How to Use a POJO Class in a Program?


 Create an object of the POJO class.
 Set values to the object's fields using the set() methods.
 Get values from the object's fields using the get() methods.

Example: MainClass.java

package Jtp.PojoDemo;

public class MainClass {


public static void main(String[] args) {
// Create an Employee object
Employee obj = new Employee(); // POJO object created

// Set values
obj.setName("Alisha");
obj.setId("A001");
obj.setSal(200000);

// Get and print values


System.out.println("Name: " + obj.getName());
System.out.println("Id: " + obj.getId());
System.out.println("Salary: " + obj.getSal());
}
}

Output:
Name: Alisha
Id: A001
Salary: 200000.0

Properties of a POJO Class :


 The class must be public so it can be accessed by other programs.
 Should have a default (no-argument) constructor.
 Can have constructors with arguments if needed.
 All fields (variables) should be private to protect data (improve
security).
 Must have getters and setters to allow controlled access to the
variables.
 The class should not extend predefined classes or implement
predefined interfaces.
 It should not use special annotations or follow forced patterns.

Q] Explain spring IOC container in details

The IoC (Inversion of Control) container is the core part of the Spring
Framework.
It is responsible for:
 Creating objects (like your classes or components).
 Configuring them (setting values or dependencies).
 Managing their lifecycle (from creation to destruction).
It uses Dependency Injection (DI) to manage objects.

How Does the IoC Container Work?


 You provide a configuration file (in XML, annotations, or Java code).
 The container reads the file to know:
 What objects to create.
 How they depend on each other.
 The container creates the objects and injects any dependencies they
need.

Types of IoC Containers :


There are two types of Spring IoC containers:

1. BeanFactory Container
2. ApplicationContext Container

1. BeanFactory Container :
 Basic container that provides simple Dependency Injection (DI).
 Uses the BeanFactory interface to handle beans.
 Commonly used when resources are limited (e.g., on mobile devices
or small applications).

Example:
HelloWorld.java

package com.example;

public class HelloWorld {


private String message; // Private variable for the message

public void setMessage(String message) { // Setter


this.message = message;
}

public void getMessage() { // Getter


System.out.println("Your Message: " + message);
}
}

MainApp.java :

package com.example;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class MainApp {


public static void main(String[] args) {
// Load the Bean configuration file
XmlBeanFactory factory = new XmlBeanFactory(new
ClassPathResource("Beans.xml"));

// Get the HelloWorld bean


HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");

// Call the method to display the message


obj.getMessage();
}
}
Beans.xml :

<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="helloWorld" class="com.example.HelloWorld">
<property name="message" value="Hello World!" />
</bean>
</beans>

Output:
Your Message: Hello World!

2. ApplicationContext Container :
 More advanced container than BeanFactory.
 It includes all BeanFactory features and provides extra functionality.
 It is recommended over BeanFactory for most applications.

HelloWorld.java :

same as above....

MainApp.java :

package com.example;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;

public class MainApp {


public static void main(String[] args) {
// Load the Bean configuration file from the file system
ApplicationContext context = new
FileSystemXmlApplicationContext("C:/path/to/Beans.xml");

// Get the HelloWorld bean


HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

// Call the method to display the message


obj.getMessage();
}
}

Beans.xml :

same as above…

Q] Explain dependancy injection and its types

Dependency Injection is a way to provide the required objects


(dependencies) to a class, rather than the class creating those objects
itself.
Think of it like ordering food at a restaurant instead of cooking it
yourself. The restaurant provides the food you need (dependency) so
you don’t have to make it on your own.
This approach makes your code more flexible, testable, and easier to
maintain.

Types of Dependency Injection :

DI can be done in two main ways:


 Constructor-based DI
 Setter-based DI

1. Constructor-Based DI :

 In Constructor-based DI, the required dependencies are provided


through the class’s constructor.
 When you create an object of the class, the required objects are
passed to it via the constructor.

Example :

Movie.java :

public class Movie {


private String movieName; // Dependency

// Constructor to inject the dependency


public Movie(String movieName) {
this.movieName = movieName;
}
}

Beans.xml :

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-
beans.xsd">

<bean id="movie" class="Movie">


<constructor-arg value="Inception"/>
</bean>

</beans>

How It Works:
movieName is the dependency needed by Movie.
When Spring creates an object of Movie, it will inject the dependency
into the constructor.

2. Setter-Based DI :

In Setter-based DI, dependencies are provided through setter methods


after the object is created.
Spring will call the setter method to set the required dependency.

Example :

Movie.java :

public class Movie {


private String movieName; // Dependency

public void setMovieFinder(String movieName) {


this.movieName = movieName;
}
}

Beans.xml :

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-
beans.xsd">

<bean id="movie" class="Movie">


<property name="movieName" value="The Dark Knight"/>
</bean>

</beans>

How It Works:
Spring creates an object of Movie and then uses the setMovieFinder()
method to inject the dependency (movieName).

Q] Explain the concept of Circular dependency

Circular Dependencies in Spring :


A circular dependency happens when two or more beans depend on
each other directly or indirectly. In simpler terms, it's when Bean A
needs Bean B to be created, and at the same time, Bean B also needs
Bean A to be created. This creates a loop where Spring can’t decide
which bean to create first.

Let’s understand this with an example:

Problem Scenario :
We have two services, ServiceA and ServiceB, that depend on each
other.

ServiceA.java:

import org.springframework.stereotype.Service;

@Service
public class ServiceA {
private ServiceB serviceB;

public ServiceA(ServiceB serviceB) {


System.out.println("Calling Service A");
this.serviceB = serviceB;
}
}

ServiceB.java:

import org.springframework.stereotype.Service;

@Service
public class ServiceB {
private ServiceA serviceA;

public ServiceB(ServiceA serviceA) {


System.out.println("Calling Service B");
this.serviceA = serviceA;
}
}
In this example:

 ServiceA depends on ServiceB (via the constructor).


 ServiceB depends on ServiceA (via the constructor).
 Now, when Spring tries to create these two services, it runs into a
problem. It needs both ServiceA and ServiceB to be created, but it
doesn’t know which one to create first. This causes a circular
dependency, and Spring throws an exception like
UnsatisfiedDependencyException.

Solution to Circular Dependency Issue :

Using @Lazy with Constructor Injection :


We can use the @Lazy annotation to tell Spring to lazily initialize one of
the beans. This means that Spring will create the bean only when it's
actually needed, rather than trying to create both beans at once.

Here’s how you can modify ServiceA to use @Lazy:

ServiceA.java:

java
Copy code
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Service
public class ServiceA {
private ServiceB serviceB;

public ServiceA(@Lazy ServiceB serviceB) {


System.out.println("Calling Service A");
this.serviceB = serviceB;
}
}
In this code, @Lazy tells Spring to delay the creation of ServiceB until it's
needed by ServiceA. Now Spring can create ServiceA first, and then
ServiceB can be created later when it’s needed, breaking the circular
dependency.
Q] Explain the concept of Overriding beans with example

Spring allows you to define a parent bean with configuration values and
then create child beans that inherit those values. The child bean can
either use the inherited configuration as-is or override it. This concept is
similar to inheritance in programming but works with Spring beans, not
Java classes.

When we talk about bean inheritance, it means that one bean can
inherit properties and configurations from another bean. You define this
relationship using the parent attribute in Spring's XML-based
configuration.

Key Concepts:
Parent Bean: A template bean that contains common configurations or
properties.
Child Bean: A bean that inherits configurations from the parent bean and
can override or add more properties.

Steps and Explanation:


1. Parent Bean Definition:

You define a parent bean (like helloWorld) and set its properties.

Example:

<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">


<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>

Here, the helloWorld bean has two properties: message1 and message2.
2. Child Bean Definition:

The child bean (like helloIndia) is defined by using the parent attribute to
inherit properties from the parent (helloWorld). The child can override
the inherited properties and add new ones.

Example:

<bean id="helloIndia" class="com.tutorialspoint.HelloIndia"


parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>

Here, helloIndia inherits message2 from helloWorld.


The message1 property is overridden to say "Hello India!".
The message3 property is newly added to helloIndia.

HelloWorld.java :

public class HelloWorld {


private String message1;
private String message2;

public void setMessage1(String message) { this.message1 = message; }


public void setMessage2(String message) { this.message2 = message; }

public void getMessage1() { System.out.println("World Message1 : " +


message1); }
public void getMessage2() { System.out.println("World Message2 : " +
message2); }
}

HelloIndia.java :

public class HelloIndia {


private String message1;
private String message2;
private String message3;

public void setMessage1(String message) { this.message1 = message; }


public void setMessage2(String message) { this.message2 = message; }
public void setMessage3(String message) { this.message3 = message; }

public void getMessage1() { System.out.println("India Message1 : " +


message1); }
public void getMessage2() { System.out.println("India Message2 : " +
message2); }
public void getMessage3() { System.out.println("India Message3 : " +
message3); }
}

Q] Explain the concept of autowiring in spring

In Spring, autowiring is a feature that allows the Spring container to


automatically inject dependencies between beans, so you don’t need to
explicitly specify which bean should be injected into another bean. This
can reduce the amount of XML configuration you need to write,
especially in large applications.

Autowiring Modes:
Q]

You might also like