Unit Iii
Unit Iii
The Spring Framework is a powerful and flexible platform designed for building Java
applications. It simplifies the development process by handling many of the complex, underlying
infrastructure tasks, allowing developers to focus on creating the actual application.
Spring makes it possible to build applications using "plain old Java objects" (POJOs) while
applying enterprise services to them. This approach works well for both simple Java SE
applications and full-fledged Java EE applications.
Here are a few examples of what you can do with the Spring Framework:
• Automatically manage database transactions without dealing with complex transaction
APIs.
• Turn a simple Java method into a remote procedure without needing to handle remote
APIs.
• Convert a local Java method into a management operation without working with JMX
APIs.
• Make a Java method handle messages without directly dealing with JMS APIs.
1.1 Core Principles#
• Before moving to Spring Framework architecture it is important to know the core
principles.
1. Dependency Injection (DI)#
Dependency Injection is a design pattern that allows the inversion of control between
components, reducing the tight coupling and making the application more modular and easier to
maintain. The Spring framework provides an Inversion of Control (IoC) container that manages
the creation and lifecycle of objects (beans) and their dependencies. The ApplicationContext is
an advanced IoC container that offers additional features like event propagation, declarative
mechanisms to create a bean, and various ways to configure your application.
2. Aspect-Oriented Programming (AOP)#
AOP is a programming paradigm that allows separation of cross-cutting concerns (aspects) from
the business logic of an application. Cross-cutting concerns such as logging, security, and
transaction management can be applied across multiple components without cluttering the core
logic.
• Aspects: An aspect is a modularization of a concern that cuts across multiple classes. In
Spring, aspects are implemented using regular classes annotated with @Aspect.
• Join Points: These are points in the program execution, such as method calls or
exception handling, where an aspect can be applied.
• Advice: This is the action taken by an aspect at a particular join point. Spring supports
various types of advice, including Before, After, Around, and AfterThrowing.
• Pointcuts: These are expressions that match join points to determine whether an advice
should be executed.
Spring’s AOP framework makes it easy to define and apply these aspects declaratively, either
through XML configuration or using annotations. This approach enhances code modularity,
promotes reuse, and simplifies maintenance.
1.2 Modules of the Spring framework#
The Spring Framework is divided into various modules, each designed to address specific
aspects of application development. These modules are grouped into several categories:
• Core Container: Includes fundamental components like IoC and DI, helping to manage
object creation and configuration.
• Data Access/Integration: Provides tools for interacting with databases, handling
transactions, and integrating with other data sources.
• Web: Supports building web applications, including MVC (Model-View-Controller)
architecture.
• AOP (Aspect-Oriented Programming) and Instrumentation: Allows adding cross-
cutting concerns like logging or security in a modular way.
• Test: Offers support for testing Spring components, ensuring that they work as expected.
Figure :- The Spring Framework consists of features organized into about 20 modules. These
modules are grouped into Core Container, Data Access/Integration, Web, AOP (Aspect Oriented
Programming), Instrumentation, and Test, as shown in the following diagram.
Spring
Architecture
1.2.1 Core Container#
The Core Container is the foundation of the Spring Framework, providing essential
functionalities for creating and managing application components, known as beans. This
container is crucial for implementing Dependency Injection (DI) and Inversion of Control (IoC)
principles, which decouple application components and promote modularity.
• Spring Core: This module provides the basic DI and IoC functionality. The IoC
container is responsible for instantiating, configuring, and assembling the beans, which
are the objects that form the backbone of a Spring application. By managing
dependencies between beans, the IoC container reduces tight coupling between
components, making the application more modular and maintainable.
• Spring Beans: This module offers the BeanFactory and BeanWrapper. The
BeanFactory is the core interface for accessing the IoC container, allowing you to retrieve
bean instances. The BeanWrapper, on the other hand, facilitates property manipulation on
Java objects, handling type conversions and other property-related operations.
• Spring Context: An advanced version of BeanFactory, ApplicationContext extends
BeanFactory to provide additional features such as internationalization support, resource
loading, and event propagation. ApplicationContext serves as a central point for
configuration and management, offering a unified view of the entire application context.
• Spring Expression Language (SpEL): SpEL is a powerful expression language that
allows you to query and manipulate objects at runtime. It supports a wide range of
operations, including property access, method invocation, arithmetic, conditionals, and
collection iteration. SpEL is deeply integrated into the Spring Framework, enabling
dynamic expressions in annotations, XML configuration, and even directly in the code.
1.2.2 Data Access/Integration#
Spring provides comprehensive support for data access and integration with various data sources,
simplifying interaction with databases and other external systems.
• Spring JDBC: This module abstracts away the complexities of raw JDBC, reducing
boilerplate code and providing a consistent exception hierarchy. Spring JDBC also
integrates seamlessly with Spring’s transaction management, offering declarative
transaction control that enhances the robustness of data access operations.
• Spring ORM: This module integrates with popular Object-Relational Mapping (ORM)
frameworks such as Hibernate, JPA, and MyBatis. It simplifies the use of ORM tools by
providing a consistent template-based approach, transaction management integration, and
support for resource management.
• Spring OXM: The Object/XML Mapping (OXM) module provides an abstraction layer
for serializing Java objects to XML and deserializing XML to Java objects. It supports a
variety of OXM frameworks like JAXB, Castor, and XStream.
• Spring JMS: This module provides a comprehensive framework for producing and
consuming messages using the Java Message Service (JMS). Spring JMS simplifies
messaging by handling resource management, connection management, and message
conversion.
• Spring Transaction: This module offers declarative transaction management, allowing
developers to manage transactions in a consistent and declarative manner across different
transactional resources (e.g., JDBC, JPA). It supports various transaction propagation and
isolation levels, making it suitable for complex transactional scenarios.
1.2.3 Web#
The Web module in Spring provides a rich set of features for building robust and scalable web
applications. It includes support for traditional servlet-based applications, reactive applications,
and integration with other frameworks.
• Spring Web: This module provides foundational web-oriented integration features, such
as multipart file upload, initialization of IoC containers using servlets, and web
application context management. It serves as the base for Spring’s web stack, including
the integration with servlets and web frameworks.
• Spring MVC (Model-View-Controller): A comprehensive framework for building web
applications using the MVC design pattern. Spring MVC supports a range of features,
including form handling, data binding, validation, and internationalization. It integrates
seamlessly with view technologies like JSP, Thymeleaf, and FreeMarker, allowing
developers to create dynamic web pages.
• Spring WebFlux: A reactive web framework that supports building non-blocking,
asynchronous applications. WebFlux is designed for high-concurrency environments and
is suitable for modern microservices architectures. It supports reactive streams and can be
deployed on various web servers, including Netty and Tomcat.
• Spring Servlet: This module provides the foundation for Spring’s web support, including
integration with the Java Servlet API. It allows for the configuration and management of
servlets, filters, and listeners within a Spring application context.
• Spring Portlet: A specialized module for building portlet-based applications, particularly
for portal environments. Spring Portlet extends the Spring MVC framework to support
JSR-168 and JSR-286 Portlet APIs, enabling developers to create modular, reusable
portlets.
• Spring Struts: This module provides integration with the Apache Struts framework,
allowing developers to use Struts with the Spring IoC container. It facilitates the
migration of legacy Struts applications to the Spring Framework while retaining the
familiar Struts architecture.
1.2.4 AOP and Instrumentation#
• Spring AOP (Aspect-Oriented Programming): AOP in Spring allows developers to
separate cross-cutting concerns (e.g., logging, security, transaction management) from the
business logic. By defining aspects, pointcuts, and advice, developers can modularize
concerns that affect multiple parts of an application, leading to cleaner and more
maintainable code. Spring AOP uses proxy-based implementation, ensuring that aspects
are applied seamlessly.
• Spring Instrumentation: This module provides support for class instrumentation and
bytecode manipulation. It is useful for creating proxy classes dynamically and is often
used in conjunction with Spring AOP and for runtime monitoring. Instrumentation can
also be used to enhance the capabilities of the Spring Framework in managed
environments like application servers.
1.2.5 Test#
• Spring Test: This module supports testing Spring applications with frameworks like
JUnit and TestNG. It provides mock objects, transaction management support, and
utilities for testing Spring components (e.g., controllers, services) in isolation or within an
application context. Spring Test also supports integration testing by providing context
configuration and dependency injection into test cases.
In this article, we covered an extensive overview of the Spring Framework, starting from its core
principles like Dependency Injection (DI) and Aspect-Oriented Programming (AOP), which
form the foundation for building modular and maintainable applications. We explored the various
modules that Spring offers, including the Core Container for managing beans, Data
Access/Integration for simplifying database interactions, Web modules for building robust web
applications, AOP and Instrumentation for handling cross-cutting concerns, and the Spring Test
module for ensuring the reliability of your code. Together, these components make Spring a
versatile and powerful framework for Java application development.
Spring MVC
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2. Java config
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller") // Specify the package where your
controllers are located
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// Configure a view resolver for rendering JSP views
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
}
What is HandlerMapping
HandlerMapping is an interface in spring-web that classes defining the mapping between
requests and their handlers (which controller handles which request) should inherit. The interface
has a single method:
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
The primary implementation of this interface is the SimpleUrlHandlerMapping class, which
maps URLs to handler beans.
What is HandlerExecutionChain
HandlerExecutionChain is a class that encapsulates the sequence of processing a request through
Interceptors to the Handler and back through Interceptors. The class has three main methods:
boolean applyPreHandle(HttpServletRequest request,
HttpServletResponse response) throws Exception
@Autowired
private PersonsService personsService;
@Controller
public class AboutController {
@GetMapping("/about")
public String about() {
return "about";
// Return the view name
(e.g., about.jsp)
}
}
Step 2: Create Multiple JSP Views
• For each controller, create corresponding JSP views in the src/main/webapp/WEB-
INF/views directory. Name the views according to the view name returned by the
controllers.
• For example, if the HomeController returns “home,” create a home.jsp file. If the
AboutController returns “about,” create an about.jsp file.
Here’s an example of a home.jsp:
<!DOCTYPE html>
<html>
<head>
<title>Home Page</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>About Page</title>
</head>
<body>
<h1>About Us</h1>
<p>We are a company that
does amazing things.</p>
</body>
</html>
Step 3: Configure View Resolver
• In your Spring MVC configuration (e.g., dispatcher-servlet.xml), configure the view
resolver to resolve view names to JSP files.
<bean class="org.springframework
.web.servlet.view
.InternalResourceViewResolver">
<property name="prefix"
value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
Step 4: Access Multiple Views
• Now, you can access the multiple views by navigating to the corresponding URLs
defined in your controllers:
• To access the home page, visit http://localhost:8080/your-web-app-context/.
• To access the about page, visit http://localhost:8080/your-web-app-context/about.
•
element and is used to create the opening and closing tags of a form. It also binds the
form to a specific model attribute.
<form:form modelAttribute="user"
method="POST"
action="/saveUser">
<!-- Form fields go here -->
</form:form>
form:input
• This tag generates an HTML input element for text input. It can be used for various input
types, such as text, password, email, etc.
<form:form modelAttribute="user"
method="POST"
action="/saveUser">
<!-- Form fields go here -->
</form:fo<form:input path="username" />
rm>
form:radiobutton
• Use this tag to create radio buttons
<form:radiobutton
path="notificationPreference"
value="EMAIL" />
<form:radiobutton
path="notificationPreference"
value="SMS" />
form:checkbox
• This tag generates checkboxes for boolean values.
<form:checkbox path="subscribed" />
form:select
• This tag generates an HTML select element for dropdown lists.
<form:select path="gender">
<form:option
value="MALE" label="Male" />
<form:option
value="FEMALE" label="Female" />
</form:select>
form:textarea
• Use this tag to create a text area input element.
<form:textarea path="description" />
form:hidden
• This tag creates a hidden input field.
<form:hidden path="id" />
n Spring MVC, the @RequestParam annotation is used to extract query parameters, form
data, or path variables from the request and map them to method parameters in the
controller. It is commonly used in request mappings for handling form submissions, URL
query parameters, or retrieving data from the URL.
Here's a detailed explanation and example of how to use @RequestParam:
1. Basic Usage
The @RequestParam annotation binds a web request parameter to a method parameter in
your controller.
java
@Controller
public class MyController {
@RequestMapping("/greet")
public String greet(@RequestParam("name") String name, Model model) {
model.addAttribute("message", "Hello, " + name);
return "greeting"; // Return view name
}
}
In the above example:
• The @RequestMapping("/greet") maps to the /greet endpoint.
• The @RequestParam("name") binds the name parameter from the query string (e.g.,
/greet?name=John) to the name method parameter.
• The greeting message is added to the model and returned to the view.
2. Optional Parameters
You can make a request parameter optional by providing a default value using the
defaultValue attribute.
@Controller
public class MyController {
@RequestMapping("/greet")
public String greet(@RequestParam(value = "name", defaultValue = "Guest") String
name, Model model) {
model.addAttribute("message", "Hello, " + name);
return "greeting"; // Return view name
}
}
In this example:
• If the name parameter is not provided in the request, the default value "Guest" will be
used.
3. Handling Multiple Parameters
You can handle multiple request parameters in a single method.
@Controller
public class MyController {
@RequestMapping("/user")
public String userDetails(@RequestParam("name") String name,
@RequestParam("age") int age, Model model) {
model.addAttribute("message", "Name: " + name + ", Age: " + age);
return "userDetails"; // Return view name
}
}
In this case, the method userDetails expects both name and age as query parameters, like
/user?name=John&age=30.
4. Handling Missing Parameters
You can also specify whether a parameter is required. By default, @RequestParam
expects the parameter to be present, but you can set required = false to make it optional.
@Controller
public class MyController {
@RequestMapping("/user")
public String userDetails(@RequestParam(value = "name", required = false) String
name, Model model) {
String message = (name != null) ? "Hello, " + name : "Hello, Guest";
model.addAttribute("message", message);
return "userDetails"; // Return view name
}
}
In this example:
• If the name parameter is not provided in the request, it will default to "Hello, Guest".
5. Binding Multiple Parameters Using @RequestParam with Map
If you expect multiple parameters with the same name or just want to handle them
dynamically, you can bind them into a Map.
@Controller
public class MyController {
@RequestMapping("/params")
public String params(@RequestParam Map<String, String> allParams, Model model)
{
model.addAttribute("params", allParams);
return "paramsView";
}
}
If the request contains parameters like /params?name=John&age=30, the Map<String,
String> will contain {"name": "John", "age": "30"}.
6. Binding to a Custom Object
You can also bind request parameters to a custom Java object using @RequestParam if
the object’s fields match the request parameters.
public class User {
private String name;
private int age;
@Controller
public class MyController {
@RequestMapping("/user")
public String userDetails(@RequestParam User user, Model model) {
model.addAttribute("message", "User: " + user.getName() + ", Age: " +
user.getAge());
return "userDetails"; // Return view name
}
}
In this case, the request could look like /user?name=John&age=30 and the User object
would be populated automatically with those values.
In a Spring MVC application, file uploading is a common task. Spring provides support
for handling file uploads in forms through the use of multipart file support. The general
approach involves configuring the necessary file upload settings, creating a form to
upload files, and handling the uploaded file in the controller.
Here’s a step-by-step guide to setting up file uploads in Spring MVC.
1. Add Dependencies
To enable file uploading, you need to include the necessary dependencies in your
pom.xml (for Maven).
<dependencies>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.x</version>
</dependency>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
This configuration tells the servlet container to handle multipart data (i.e., file uploads) in
the request.
3. Create a Form to Upload Files
Now, create an HTML form where users can select and upload files. You'll need to set the
enctype attribute to multipart/form-data to allow the form to handle file data.
Example HTML Form (JSP):
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
4. Controller to Handle File Upload
In your Spring MVC controller, you can handle the file upload using @RequestParam for
the file parameter.
Example Controller:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import java.io.File;
import java.io.IOException;
@Controller
public class FileUploadController {
@PostMapping("/upload")
public ModelAndView handleFileUpload(@RequestParam("file") MultipartFile file) {
ModelAndView modelAndView = new ModelAndView();
if (!file.isEmpty()) {
try {
// Get the file and save it locally
String filePath = UPLOAD_DIR + file.getOriginalFilename();
File dest = new File(filePath);
file.transferTo(dest);
modelAndView.setViewName("uploadSuccess");
modelAndView.addObject("message", "File uploaded successfully!");
} catch (IOException e) {
modelAndView.setViewName("uploadFailure");
modelAndView.addObject("message", "Failed to upload file.");
}
} else {
modelAndView.setViewName("uploadFailure");
modelAndView.addObject("message", "No file selected.");
}
return modelAndView;
}
}
5. Configuration for MultipartResolver (Optional)
If you're using Java configuration, you need to define the MultipartResolver bean in your
@Configuration class.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Configuration
public class AppConfig {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10485760); // 10MB
resolver.setMaxInMemorySize(1048576); // 1MB
return resolver;
}
}
6. Handle Upload Result in the View
In your JSP or HTML view, you can display the result of the upload operation.
Example uploadSuccess.jsp:
<h1>${message}</h1>
Example uploadFailure.jsp:
<h1>${message}</h1>
7. Configure Application Properties (Optional)
You can configure additional properties related to file uploads in your
application.properties file (if using Spring Boot or Spring Framework with Spring Boot-
like configuration).
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=20MB
In Spring MVC, validation is an essential part of handling form submissions and ensuring
that the data entered by users is correct. Spring provides powerful validation mechanisms
that can be integrated with forms using annotations, and these can be extended with
custom validation logic using regular expressions or numeric constraints.
Here’s a detailed explanation of how to implement validation in Spring MVC, including
validation with regular expressions and numbers.
@NotNull
@Size(min = 2, max = 30)
private String name;
@Email
private String email;
@NotNull
private String password;
import javax.validation.Valid;
@Controller
public class UserController {
@RequestMapping("/register")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "userForm";
}
@RequestMapping("/submitForm")
public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult
bindingResult) {
if (bindingResult.hasErrors()) {
return "userForm"; // Return to the form view with validation errors
}
return "success";
}
}
In the above example:
• The @NotNull, @Size, and @Email annotations perform validation.
• The BindingResult is used to check for validation errors.
@Constraint(validatedBy = PhoneNumberValidator.class)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPhoneNumber {
String message() default "Invalid phone number format";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2. Create the Validator Class:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
@Override
public void initialize(ValidPhoneNumber constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && value.matches(PHONE_REGEX);
}
}
3. Use the Custom Validator in the Model Class:
public class User {
@ValidPhoneNumber
private String phoneNumber;
Here’s a simplified version of a CRUD application using Spring MVC with Spring
Data JPA. This example will cover basic operations (Create, Read, Update, Delete) with
minimal configuration and a focus on simplicity.
Step-by-Step Example
1. Add Dependencies (pom.xml)
If you're using Maven, include the following dependencies in your pom.xml for Spring
MVC, Spring Data JPA, and H2 (an in-memory database).
<dependencies>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.x</version>
</dependency>
<!-- Spring Boot Starter Data JPA (Optional if using Spring Boot) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
2. Configure Application Properties
Configure H2 as an in-memory database and set up basic JPA properties in
application.properties.
# H2 Database Configuration (In-memory database for simplicity)
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
3. Create Entity Class
The entity will represent a simple Student table in the database.
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Student {
@Id
private Long id;
private String name;
private String email;
import java.util.List;
@Controller
@RequestMapping("/students")
public class StudentController {
@Autowired
private StudentRepository studentRepository;