Spring MVC follows a request-driven design pattern, commonly referred to as Model-View-Controller (MVC). Here's a high-level overview of how it works:
- Client Request: The client sends a request to the server.
- DispatcherServlet: The request is received by the
DispatcherServlet
, which acts as the front controller. - Handler Mapping: The
DispatcherServlet
consults the Handler Mapping to call the appropriate Controller based on the request URL. - Controller: The Controller processes the request and interacts with the Service layer to handle business logic.
- Service Layer: The Service layer processes the business logic, often interacting with the DAO layer to perform CRUD operations.
- DAO Layer: The DAO layer interacts with the database to retrieve or store data.
- Model: The data retrieved from the DAO layer is encapsulated in a Model object.
- View Resolver: The
DispatcherServlet
consults the View Resolver to select the appropriate view based on the view name returned by the Controller. - View: The selected view is rendered and returned to the client.
+-------------------+
| Client |
+--------+----------+
|
v
+--------+----------+ +-----------------+
| Dispatcher | | Handler |
| Servlet +--------->| Mapping |
+--------+----------+ +-----------------+
|
v
+--------+----------+
| Controller |
+--------+----------+
|
v
+--------+----------+ +-----------------+
| Service +<-------->| DAO |
+--------+----------+ +-----------------+
|
v
+--------+----------+
| Model |
+--------+----------+
|
v
+--------+----------+ +-----------------+
| View Resolver +<-------->| View |
+--------+----------+ +-----------------+
|
v
+--------+----------+
| Client |
+-------------------+
Client Request --> DispatcherServlet --> HandlerMapping --> Controller --> Model --> View Name
↓
ViewResolver --> View --> Response
The process starts with the client sending a request to the server.
Client -> HTTP Request -> DispatcherServlet
The DispatcherServlet
is the front controller that receives all incoming requests.
DispatcherServlet -> Front Controller
The DispatcherServlet
uses Handler Mapping to determine which controller method should handle the request.
DispatcherServlet -> Handler Mapping -> Controller
The Controller processes the request. It calls the appropriate service methods to handle the business logic.
Controller -> Business Logic -> Service Layer
The Service layer processes the business logic and interacts with the DAO layer to perform data access operations.
Service Layer -> DAO Layer
The DAO layer interacts with the database to retrieve or store data.
DAO Layer -> Database
The data retrieved from the DAO layer is encapsulated in a Model object.
Service Layer -> Model
The DispatcherServlet
consults the View Resolver to select the appropriate view based on the view name returned by the Controller.
DispatcherServlet -> View Resolver -> View
The selected view is rendered and returned to the client.
View -> Rendered Response -> Client
Below is a more detailed sequence diagram of the interaction between the components in Spring MVC.
Client -> DispatcherServlet: Request
DispatcherServlet -> HandlerMapping: Find Controller
HandlerMapping -> DispatcherServlet: Return Controller
DispatcherServlet -> Controller: Invoke Controller
Controller -> Service: Business Logic
Service -> DAO: Data Access
DAO -> Database: Query
Database -> DAO: Result
DAO -> Service: Data
Service -> Controller: Processed Data
Controller -> Model: Add Data
Controller -> DispatcherServlet: View Name
DispatcherServlet -> ViewResolver: Resolve View
ViewResolver -> DispatcherServlet: View
DispatcherServlet -> View: Render
View -> DispatcherServlet: Response
DispatcherServlet -> Client: Response
Folder Structure
SpringMVCProject/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── config/
│ │ │ │ └── WebConfig.java
│ │ │ ├── controller/
│ │ │ │ └── HomeController.java
│ │ │ ├── model/
│ │ │ │ └── User.java
│ │ │ ├── repository/
│ │ │ │ └── UserRepository.java
│ │ │ └── service/
│ │ │ └── UserService.java
│ │ ├── resources/
│ │ │ └── application.properties
│ │ ├── webapp/
│ │ │ ├── WEB-INF/
│ │ │ │ ├── views/
│ │ │ │ │ └── index.jsp
│ │ │ │ └── web.xml
│ │ │ └── index.jsp
│ ├── test/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── UserServiceTests.java
├── pom.xml
└── README.md
package com.example.myapp.controller;
import com.example.myapp.model.User;
import com.example.myapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public String getUserById(@PathVariable Long id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "userDetail";
}
}
package com.example.myapp.service;
import com.example.myapp.model.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
package com.example.myapp.repository;
import com.example.myapp.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
package com.example.myapp.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
// Getters and Setters
}
<!-- src/main/resources/templates/userDetail.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>User Detail</title>
</head>
<body>
<h1>User Detail</h1>
<div>
<p>ID: <span th:text="${user.id}"></span></p>
<p>First Name: <span th:text="${user.firstName}"></span></p>
<p>Last Name: <span th:text="${user.lastName}"></span></p>
<p>Email: <span th:text="${user.email}"></span></p>
</div>
</body>
</html>
By following this structure and flow, you can create a well-organized and maintainable Spring MVC application.