Coming soon! #


What is Model 1 architecture? #

graph 
    Browser["Browser Sends Request"] --> FrontController["Front Controller: Handles All Requests"]
    FrontController --> Controller["Controller: Processes Business Logic"]
    Controller --> Model["Model: Accesses Data"]
    Controller --> FrontController
    FrontController --> View["View: Renders the UI"]
    View -->FrontController
    FrontController --> |Sends Response| Browser

Model 1 architecture is the most basic web application architecture, where all the logic and processing happen directly inside a JSP (Java Server Page). Here's how it works:

  • The browser sends a request directly to a JSP page.
  • The JSP handles everything:
    • Retrieves data from the database.
    • Populates the model with data.
    • Renders the view for the user.

Key Characteristics:

  • No servlets or separate controllers are used.
  • The JSP is responsible for handling all logic (business, presentation, and data access).

Drawbacks:

  • Complexity in Maintenance: As the application grows, JSPs become bloated and hard to maintain because they handle everything.
  • Poor Separation of Concerns: There’s no clear distinction between the roles of the model, view, and controller.

Example Flow:

  1. Browser sends a request to data.jsp.
  2. The JSP retrieves data, processes it, and displays the result directly.

What is Model 2 architecture? #

Model 2 architecture introduces a clear separation of concerns using the Model-View-Controller (MVC) pattern. Here’s how it works:

  1. Request Handling:
    • The browser sends a request to a Servlet (the controller).
  2. Business Logic:
    • The Servlet processes the request.
    • It retrieves or updates data in the Model (e.g., database).
  3. Response Rendering:
    • The Servlet forwards the data to a View (e.g., JSP) for rendering.
  4. The View displays the result to the user.

Key Components:

  • Model: Represents the application’s data and business logic.
  • View: Responsible for displaying data (e.g., JSP, Freemarker templates).
  • Controller: Handles user input, updates the model, and decides which view to render.

Advantages:

  • Clear Separation of Concerns: The model, view, and controller have distinct roles.
  • Easier Maintenance: Business logic and presentation logic are kept separate.

Example Flow:

  1. Browser sends a request to DataController.
  2. The Servlet processes the request, interacts with the database, and prepares the data model.
  3. The Servlet forwards the request to data.jsp for rendering.
  4. The JSP displays the data to the user.

What is Model 2 Front Controller architecture? #

Model 2 Front Controller architecture enhances the Model 2 pattern by introducing a Front Controller, which acts as a central point for handling all incoming requests.

How it Works:

  1. All requests from the browser are directed to the Front Controller.
  2. The Front Controller:
    • Processes the request (e.g., handles authentication, logging, or security checks).
    • Delegates the request to the appropriate Servlet or controller for further processing.
  3. The controller interacts with the model to process the business logic.
  4. The Front Controller decides which View (e.g., JSP) to render.
  5. The View generates the response, and the Front Controller sends it back to the browser.

Advantages:

  • Centralized Request Handling: All requests pass through a single point, simplifying security, logging, and global pre-processing.
  • Reusability: Common functionality (e.g., authentication) can be implemented at the Front Controller level, avoiding redundancy.

Example in Spring MVC:

  • In Spring MVC, the DispatcherServlet is the Front Controller.
  • It routes requests to the appropriate controllers based on configuration.

Example Flow:

  1. Browser sends a request to /home.
  2. The Front Controller (e.g., DispatcherServlet) intercepts the request.
  3. It forwards the request to HomeController.
  4. The controller interacts with the model, processes data, and returns it to the Front Controller.
  5. The Front Controller renders the view (e.g., home.jsp) and sends the response back.

Can you show an example controller method in Spring MVC? #

Here’s a basic example of a controller method in Spring MVC that handles a GET request:

@Controller
public class TodoController {

    @RequestMapping(value = "/list-todos", method = RequestMethod.GET)
    public String listTodos(Model model) {
        List<String> todos = List.of("Learn Spring MVC", "Learn Java", "Practice Coding");
        model.addAttribute("todos", todos); // Adding data to the model
        return "listTodos"; // Name of the view to render
    }
}

Explanation:

  • @Controller: Indicates this class is a Spring MVC controller.
  • @RequestMapping:
    • value: Maps the /list-todos URL to this method.
    • method: Specifies the HTTP method (GET in this case).
  • Model: Holds the data (todos) that will be passed to the view.
  • Return Value: The name of the view (listTodos.jsp) that will be rendered.


Why is the @ResponseBody annotation used? #

  • The @ResponseBody annotation tells Spring to directly return the value from the method as the HTTP response body, instead of looking for a view template.
  • Without @ResponseBody, Spring would try to resolve the returned string as a view name.

Can you explain a simple flow in Spring MVC? #

graph architecture {
node[style=filled]
rankdir = LR
node[shape=record, width=1.6]

Browser[label=]
DispatcherServlet[label=]
HandlerMapping[label=]
Controller[label=]
Model[label=]
ViewResolver[label=]
View[label=]

Browser -- DispatcherServlet
DispatcherServlet -- HandlerMapping
HandlerMapping -- Controller
Controller -- Model
Controller -- DispatcherServlet
DispatcherServlet -- ViewResolver
ViewResolver -- View
View -- Browser [label=]
}

Here’s the flow of a request in Spring MVC:

  1. Browser Request:

    • A user types a URL (e.g., /list-todos) or clicks a link.
  2. DispatcherServlet:

    • The request first goes to the DispatcherServlet, which acts as the Front Controller.
    • It determines which controller should handle the request by consulting handler mappings.
  3. Controller Execution:

    • The controller method processes the request.
    • It interacts with the service or database to get the required data.
    • It populates the Model with the data and returns the name of the view.
  4. ViewResolver:

    • The ViewResolver maps the view name (e.g., listTodos) to the actual file (e.g., /WEB-INF/views/listTodos.jsp).
  5. Rendering the View:

    • The view (e.g., JSP) is rendered using the data from the Model.
    • The response (HTML) is sent back to the browser.

What is a ViewResolver? #

A ViewResolver maps the logical view name returned by a controller (e.g., listTodos) to the actual view file (e.g., WEB-INF/views/listTodos.jsp).

Example Configuration in application.properties:

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
  • Prefix: /WEB-INF/views/
  • Suffix: .jsp

If the controller returns listTodos, the ViewResolver maps it to /WEB-INF/views/listTodos.jsp.


What is Model? #

A Model in Spring MVC holds the data that the controller passes to the view.

Example Usage:

public String listTodos(Model model) {
    model.addAttribute("todos", List.of("Learn Spring", "Learn Hibernate"));
    return "listTodos";
}
  • Purpose: Makes data available to the view.
  • How It Works: The controller adds data to the model, and the view accesses it using JSTL or other templating tools.

JSP Example:


    
  • ${todo}

  • What is ModelAndView? #

    ModelAndView is an alternative to using the Model and view name separately. It combines both into a single object.

    Example Usage:

    @RequestMapping("/welcome")
    public ModelAndView welcome() {
        ModelAndView mv = new ModelAndView("welcome"); // View name
        mv.addObject("message", "Welcome to Spring MVC!"); // Add data to the model
        return mv;
    }

    Explanation:

    • The view name (welcome) and data (message) are set in the same object.
    • This approach is less commonly used because separating the model and view improves readability.

    What is a RequestMapping? #

    @RequestMapping is an annotation used in Spring MVC to map HTTP requests to specific controller methods.

    Key Elements:

    • value: Specifies the URL pattern (e.g., /list-todos).
    • method: Specifies the HTTP method (e.g., GET, POST).

    Example:

    @RequestMapping(value = "/list-todos", method = RequestMethod.GET)
    public String listTodos(Model model) {
        // Logic here
        return "listTodos";
    }

    Shortcut for Common HTTP Methods:

    • @GetMapping("/list-todos"): Shortcut for @RequestMapping(method = RequestMethod.GET).
    • @PostMapping("/add-todo"): Shortcut for @RequestMapping(method = RequestMethod.POST).

    What is Dispatcher Servlet? #

    The DispatcherServlet is the Front Controller in Spring MVC. It acts as the central point for handling all incoming HTTP requests and orchestrating the overall request-response flow in a Spring MVC application.

    Key Responsibilities:

    1. Request Handling:
      • It intercepts all incoming requests and directs them to the appropriate controllers based on handler mappings.
    2. Mapping Views:
      • It determines which view (e.g., JSP, Thymeleaf) should render the response using a ViewResolver.
    3. Integration with Spring Components:
      • It works seamlessly with other Spring components like HandlerMapping, HandlerAdapter, and ViewResolver.

    Flow in Spring MVC:

    • A user sends a request.
    • The DispatcherServlet receives the request.
    • It looks up the appropriate controller using handler mappings.
    • The controller processes the request, populates the model, and returns the view name.
    • The DispatcherServlet uses a ViewResolver to find the correct view.
    • The view is rendered and sent back to the user.

    How do you set up Dispatcher Servlet? #

    Setting up the DispatcherServlet depends on whether you're using a traditional Spring MVC configuration or Spring Boot.

    1. Traditional Spring MVC Configuration (using web.xml):

    You need to configure the DispatcherServlet in the web.xml file.

    Example Configuration:

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/todo-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    Explanation:

    • Servlet Declaration (<servlet>):
      • The DispatcherServlet is declared as a standard HttpServlet.
      • contextConfigLocation specifies the location of the Spring configuration file (e.g., /WEB-INF/todo-servlet.xml).
      • load-on-startup ensures the servlet is loaded when the application starts.
    • Servlet Mapping (<servlet-mapping>):
      • Maps all requests (/*) or specific URLs (e.g., /springmvc/*) to the DispatcherServlet.

    Spring Context File (todo-servlet.xml): This file defines the Spring MVC configuration, such as controllers, view resolvers, and handler mappings.

    2. Spring Boot Configuration:

    In Spring Boot, the DispatcherServlet is automatically configured for you. No need to define it in web.xml or manually set up configuration files.

    How It Works:

    • When the spring-boot-starter-web dependency is added to your project, Spring Boot:
      • Detects that it's a web application.
      • Automatically configures the DispatcherServlet and maps it to /.

    Dependency in pom.xml:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    What is a form backing object? #

    A form backing object is a server-side representation of a form in Spring MVC. It is the Java object that holds the data entered into a form by the user. This object connects the form fields to your application’s backend.

    How it Works:

    1. A form backing object is created in the controller and added to the model.
    2. The form fields in the view (e.g., JSP) are mapped to the properties of this object.
    3. When the form is submitted, the form data is bound to the object, and the controller processes it.

    Example:

    @Controller
    public class TodoController {
    
        @GetMapping("/add-todo")
        public String showAddTodoPage(Model model) {
            model.addAttribute("todo", new Todo()); // Form backing object
            return "addTodo";
        }
    
        @PostMapping("/add-todo")
        public String addTodo(@Valid @ModelAttribute("todo") Todo todo, BindingResult result) {
            if (result.hasErrors()) {
                return "addTodo";
            }
            // Save the todo and redirect
            return "redirect:/list-todos";
        }
    }

    JSP Example:

    
        Description:
        
        
        
        Target Date:
        
        
    
        
    

    How is validation done using Spring MVC? #

    Validation in Spring MVC is achieved using the Java Validation API (e.g., @Valid) and annotations provided by the Hibernate Validator (default implementation).

    Steps for Validation:

    1. Add Validation Annotations:

      • Annotate the properties of the form backing object with validation constraints like @Size, @NotNull, @Past, etc.
      public class Todo {
          @Size(min = 6, message = "Description must be at least 6 characters.")
          private String description;
      
          @NotNull(message = "Target date is required.")
          private LocalDate targetDate;
      
          // Getters and setters
      }
    2. Use @Valid in Controller:

      • Apply the @Valid annotation to the form backing object in the controller.
      • Include a BindingResult to capture validation errors.
      @PostMapping("/add-todo")
      public String addTodo(@Valid @ModelAttribute("todo") Todo todo, BindingResult result) {
          if (result.hasErrors()) {
              return "addTodo";
          }
          return "redirect:/list-todos";
      }
    3. Display Errors in the View:

      • Use the form:errors tag to display validation error messages.

    What is BindingResult? #

    BindingResult is an object in Spring MVC that holds the results of form validation and data binding. It stores any errors detected during the binding or validation process.

    Key Points:

    • It must immediately follow the @Valid parameter in the controller method signature.
    • Use result.hasErrors() to check if there are validation errors.

    Example:

    @PostMapping("/add-todo")
    public String addTodo(@Valid @ModelAttribute("todo") Todo todo, BindingResult result) {
        if (result.hasErrors()) {
            return "addTodo";
        }
        return "redirect:/list-todos";
    }

    How do you map validation results to your view? #

    Validation results are mapped to the view using BindingResult and displayed with Spring Form Tags.

    Steps:

    1. Perform validation in the controller and store errors in BindingResult.

      @PostMapping("/add-todo")
      public String addTodo(@Valid @ModelAttribute("todo") Todo todo, BindingResult result) {
          if (result.hasErrors()) {
              return "addTodo"; // Return the view to display errors
          }
          return "redirect:/list-todos";
      }
    2. Use the form:errors tag in the view to display error messages.

    3. Customize error messages using validation annotations in the form backing object.

      @Size(min = 6, message = "Description must be at least 6 characters.")
      private String description;

    What are Spring Form Tags? #

    Spring Form Tags are part of the Spring MVC Tag Library and are used to simplify working with forms in JSP views.

    Common Spring Form Tags:

    • <form:form>: Creates a form bound to a model attribute.
    • <form:label>: Creates a label for a form field.
    • <form:input>: Renders an input field.
    • <form:errors>: Displays validation errors for a specific field.

    Example:

    
        Description:
        
        
    
        Target Date:
        
        
    
        
    

    Key Features:

    • Automatically binds form fields to the form backing object.
    • Simplifies error handling with the form:errors tag.

    What is a Path Variable? #

    A Path Variable is a placeholder in the URL that can capture dynamic values. It allows you to pass data within the URL path and map it directly to a method parameter in a Spring MVC controller.

    How It Works:

    • Define a placeholder in the URL using curly braces {}.
    • Use the @PathVariable annotation in the controller method to map the URL segment to a variable.

    Example:

    @Controller
    public class TodoController {
    
        @GetMapping("/todos/{id}")
        public String retrieveTodo(@PathVariable("id") int id, Model model) {
            Todo todo = todoService.getTodoById(id); // Retrieve todo by ID
            model.addAttribute("todo", todo);
            return "todoDetails"; // View name
        }
    }

    Explanation:

    • URL: /todos/1
    • The value 1 in the URL is mapped to the id parameter in the method.
    • The controller retrieves the Todo with ID 1 and adds it to the model.

    Key Benefits:

    • Enables clean and RESTful URLs.
    • Useful for identifying resources in web services (e.g., /todos/{id}).

    What is a Model Attribute? #

    A Model Attribute is used to bind data between the controller and the view. It populates the model with data that can be accessed and displayed in the view.

    How It Works:

    1. Use @ModelAttribute in a controller method to populate attributes.
    2. The attributes are automatically added to the model for all request mappings in the controller.

    Example:

    @Controller
    public class TodoController {
    
        @ModelAttribute("options")
        public List<String> populateOptions() {
            return Arrays.asList("Option1", "Option2", "Option3");
        }
    
        @GetMapping("/add-todo")
        public String showAddTodoPage(Model model) {
            model.addAttribute("todo", new Todo());
            return "addTodo";
        }
    }

    Explanation:

    • The @ModelAttribute("options") method adds a list of options to the model.
    • These options are accessible in all views rendered by methods in this controller.

    Usage in JSP:

    
        
    

    Benefits:

    • Reduces repetitive code by making common attributes available to all controller methods.
    • Useful for populating dropdowns or other reusable components.

    What is a Session Attribute? #

    A Session Attribute is used to store attributes in the session for maintaining state across multiple HTTP requests from the same user.

    How It Works:

    1. Use @SessionAttributes at the controller level to specify which model attributes should be stored in the session.
    2. These attributes are persisted in the session and can be reused across multiple requests.

    Example:

    @Controller
    @SessionAttributes("user")
    public class UserController {
    
        @GetMapping("/login")
        public String login(Model model) {
            User user = new User("John Doe"); // Retrieve user details
            model.addAttribute("user", user); // Add user to the session
            return "welcome";
        }
    
        @GetMapping("/profile")
        public String showProfile(@ModelAttribute("user") User user) {
            // Use the user from the session
            return "profile";
        }
    }

    Explanation:

    • @SessionAttributes("user"): The user attribute from the model is stored in the session.
    • The user attribute can be accessed in subsequent requests without fetching it again from the database.

    Benefits:

    • Reduces redundant database queries for attributes that don’t change frequently (e.g., user details).
    • Helps maintain conversational state across multiple requests.

    What is an @InitBinder? #

    @InitBinder is an annotation in Spring MVC used to customize the data binding process for a specific controller. It allows you to define custom logic for converting request parameters into the appropriate object types, such as handling custom date formats.

    Key Features:

    • Enables fine-grained control over data binding and formatting.
    • Used to register custom editors or formatters for specific fields or types.
    • Applied at the method level in a controller.

    When It’s Invoked:

    • During the binding process, when a form is submitted or data is passed in a request.
    • It converts the incoming data (e.g., a string) into the required Java object type (e.g., Date).

    How do you set a default date format with Spring? #

    You can use @InitBinder along with CustomDateEditor to set a default date format for your Spring MVC application. This ensures consistent date handling across your forms and requests.

    Steps to Set Default Date Format:

    1. Create an @InitBinder Method:

      • Define a method in your controller and annotate it with @InitBinder.
      • Use CustomDateEditor to specify the date format.
    2. Set the Date Format for All Fields of Type Date:

      • Use SimpleDateFormat to define the desired format.
      • Register the CustomDateEditor for the Date class.

    Example Implementation:

    @Controller
    public class TodoController {
    
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            // Define the date format (dd-MM-yyyy)
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            dateFormat.setLenient(false);
    
            // Register the custom editor for Date class
            binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
        }
    
        @GetMapping("/add-todo")
        public String showAddTodoPage(Model model) {
            model.addAttribute("todo", new Todo());
            return "addTodo";
        }
    
        @PostMapping("/add-todo")
        public String addTodo(@ModelAttribute("todo") Todo todo) {
            // Save the todo
            return "redirect:/list-todos";
        }
    }

    Explanation:

    1. @InitBinder Method:
      • Customizes the binding for the Date class.
      • Registers a CustomDateEditor with the specified SimpleDateFormat.
    2. Date Conversion:
      • When a form field (e.g., targetDate) is submitted, Spring automatically converts the input string ("29-12-2024") into a Date object using the provided format.

    How do you implement common logic for controllers in Spring MVC? #

    To implement common logic across all controllers in Spring MVC, you use Controller Advice. This allows you to centralize code that applies to multiple controllers, such as:

    • Exception Handling: Define how exceptions across the application are handled.
    • Data Binding Customizations: Configure common @InitBinder methods for all controllers.
    • Global Model Attributes: Share attributes across all controllers.

    Example:

    @ControllerAdvice
    public class GlobalControllerAdvice {
    
        @ExceptionHandler(Exception.class)
        public String handleGlobalException(Exception ex, Model model) {
            model.addAttribute("error", "An unexpected error occurred!");
            return "error"; // Redirects to error.jsp
        }
    
        @ModelAttribute("appName")
        public String addGlobalAttributes() {
            return "My Application";
        }
    }

    Key Points:

    • @ControllerAdvice: Specifies that the class contains shared logic for all controllers.
    • Centralized Logic: Reduces repetitive code and makes applications easier to maintain.

    What is a Controller Advice? #

    @ControllerAdvice is an annotation in Spring MVC used to define global logic for multiple controllers. It’s a way to apply cross-cutting concerns, like exception handling and model attribute management, in a centralized manner.

    Key Features:

    1. Global Exception Handling: Handle exceptions for all controllers in one place.
    2. Model Attributes: Add common attributes to the model for use in all views.
    3. InitBinder Configuration: Define data binding customizations that apply across all controllers.

    Example Use Cases:

    • Handle specific exceptions across all controllers.
    • Add global model attributes (e.g., app name or user information).
    • Standardize data binding (e.g., date formats).

    What is @ExceptionHandler? #

    The @ExceptionHandler annotation is used to handle exceptions thrown by controller methods. It defines specific logic to execute when an exception occurs.

    Key Points:

    • It can handle specific exceptions or a hierarchy of exceptions.
    • It can be used in individual controllers or combined with @ControllerAdvice for global exception handling.

    Example in a Specific Controller:

    @Controller
    public class TodoController {
    
        @ExceptionHandler(TodoNotFoundException.class)
        public String handleTodoNotFoundException(TodoNotFoundException ex, Model model) {
            model.addAttribute("error", ex.getMessage());
            return "error"; // Redirects to error.jsp
        }
    }

    Example in @ControllerAdvice:

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(Exception.class)
        public String handleAllExceptions(Exception ex, Model model) {
            model.addAttribute("error", "Something went wrong: " + ex.getMessage());
            return "error"; // Global error page
        }
    }

    How It Works:

    1. The annotation specifies the type of exception to handle (e.g., TodoNotFoundException, Exception).
    2. When an exception is thrown, Spring invokes the method annotated with @ExceptionHandler to handle it.

    Why is Spring MVC so popular? #

    Spring MVC has become one of the most widely used frameworks for web application development due to its powerful features, flexibility, and ease of use.

    1. Clear Separation of Concerns:

    • Spring MVC enforces the Model-View-Controller (MVC) design pattern, which separates the business logic, presentation logic, and request handling:
      • Model: Manages application data and business logic.
      • View: Responsible for rendering the user interface (e.g., JSP, Thymeleaf).
      • Controller: Handles user input and updates the model.
    • Each component handles one responsibility, making the application modular and easier to maintain.

    2. DispatcherServlet as the Central Coordinator:

    • Acts as the Front Controller, managing the entire request-response lifecycle.
    • Delegates requests to the appropriate controllers and resolves views with the help of ViewResolvers.

    3. Flexibility and Extensibility:

    • Supports a wide variety of view technologies (e.g., JSP, Thymeleaf, Freemarker).
    • Provides integration with other Spring modules (e.g., Spring Security, Spring Data).
    • Highly configurable, allowing developers to fine-tune the framework to fit specific requirements.

    4. Simplified Development of RESTful Web Services:

    • Spring MVC can seamlessly handle REST API development.
    • Includes annotations like @RestController, @GetMapping, and @PostMapping, making it easy to create RESTful endpoints.

    Example:

    @RestController
    @RequestMapping("/api/todos")
    public class TodoController {
    
        @GetMapping
        public List<Todo> getAllTodos() {
            return todoService.findAll();
        }
    }

    5. Built-in Validation and Data Binding:

    • Automatically binds form data to Java objects using annotations like @ModelAttribute.
    • Includes robust validation capabilities with support for the Java Validation API (@Valid, @Size, etc.).

    6. Testability:

    • The modular architecture and dependency injection make it easy to unit test individual components (e.g., controllers).
    • Tools like MockMvc allow for testing the web layer without starting a full server.

    Example Test:

    @RunWith(SpringRunner.class)
    @WebMvcTest(TodoController.class)
    public class TodoControllerTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        public void testGetAllTodos() throws Exception {
            mockMvc.perform(get("/api/todos"))
                   .andExpect(status().isOk());
        }
    }

    7. Wide Community and Ecosystem:

    • A vast community of developers ensures excellent support, rich documentation, and numerous resources.
    • Integration with Spring Boot further simplifies configuration and setup.

    8. Reusability Across Web and REST Applications:

    • Spring MVC is not limited to traditional web applications. It’s also extensively used for building RESTful web services, making it a versatile framework.