模型 1 架構 是一種用於開發 Web 應用程式的早期設計模式。在此架構中,JSP(JavaServer Pages)扮演核心角色,處理表示和業務邏輯。
如上圖所示,有一張圖片顯示了 Model1 架構的流程。
流程:
特徵:
缺點:
Model 2 架構 是一種用於開發 Web 應用程式的高階設計模式,通常稱為 MVC(模型-視圖-控制器)架構。它將應用程式邏輯分為三個主要元件:模型、視圖和控制器。
流程:
組件:
特徵:
Model 2 前端控制器架構 是 Model 2 (MVC) 架構的改進,其中單一控制器(稱為前端控制器)處理所有傳入請求。此模式進一步將請求處理邏輯與業務邏輯和視圖渲染解耦。
流程:
組件:
特徵:
@Controller public class MyController { @RequestMapping("/hello") public String sayHello(Model model) { model.addAttribute("message", "Hello, World!"); return "helloView"; } }
總結:上面的範例示範了 Spring MVC 中的一個簡單控制器方法,它將 /hello 請求對應到 sayHello 方法。此方法會為模型新增一則訊息並傳回一個視圖名稱(helloView)。
Summary: A Spring MVC request flow starts with a client request and goes through the DispatcherServlet, HandlerMapping, and controller. The controller interacts with the model, returns a view name, and the ViewResolver resolves it to a physical view which is then rendered and returned to the client.
A ViewResolver is a component in Spring MVC that resolves view names to actual view files. It maps the logical view name returned by the controller to a specific view implementation (e.g., JSP file, Thymeleaf template).
Example:
@Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; }
Summary: A ViewResolver in Spring MVC maps logical view names to physical view files, enabling the separation of view names in controllers from the actual view files.
A Model in Spring MVC is an interface that provides a way to pass attributes to the view for rendering. It acts as a container for the data to be displayed in the view.
Example:
@Controller public class MyController { @RequestMapping("/hello") public String sayHello(Model model) { model.addAttribute("message", "Hello, World!"); return "helloView"; } }
Summary: The Model in Spring MVC is used to pass data from the controller to the view. It allows adding attributes that will be available in the view for rendering.
ModelAndView is a holder for both the model and the view in Spring MVC. It encapsulates the data (model) and the view name or view object in one object.
Example:
@Controller public class MyController { @RequestMapping("/greeting") public ModelAndView greeting() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("greetingView"); modelAndView.addObject("message", "Hello, Spring MVC!"); return modelAndView; } }
Summary: ModelAndView in Spring MVC combines both the model data and the view name into one object, simplifying the return type from controllers when both model and view need to be specified.
@RequestMapping is an annotation used to map HTTP requests to handler methods of MVC and REST controllers. It can map requests based on URL, HTTP method, request parameters, headers, and media types.
Example:
@Controller @RequestMapping("/home") public class HomeController { @RequestMapping(value = "/welcome", method = RequestMethod.GET) public String welcome(Model model) { model.addAttribute("message", "Welcome to Spring MVC!"); return "welcomeView"; } }
Summary: @RequestMapping is an annotation in Spring MVC that maps HTTP requests to specific controller methods based on URL patterns, HTTP methods, and other parameters, allowing precise routing of requests.
Controller Method:
Flow in Spring MVC:
ViewResolver:
Model:
ModelAndView:
RequestMapping:
The DispatcherServlet is the central dispatcher for HTTP request handlers/controllers in a Spring MVC application. It is responsible for routing incoming web requests to appropriate controller methods, handling the lifecycle of a request, and returning the appropriate response.
In a traditional Spring MVC application, you set up the DispatcherServlet in the web.xml configuration file or via Java configuration.
Using web.xml:
<web-app> <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/spring/dispatcher-config.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> </web-app>
Using Java Configuration:
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { RootConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
In this setup, RootConfig and WebConfig are configuration classes annotated with @Configuration.
No, in Spring Boot, you do not need to explicitly set up the DispatcherServlet. Spring Boot automatically configures the DispatcherServlet for you. By default, it is mapped to the root URL pattern (/), and Spring Boot will scan your classpath for @Controller and other related annotations.
Spring Boot Application Class:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class, args); } }
In this setup, Spring Boot handles the DispatcherServlet setup internally, allowing you to focus on your application's logic without worrying about the boilerplate configuration.
A form backing object in Spring MVC is a Java object that is used to capture form input data. It acts as a data holder for form fields, facilitating the transfer of form data between the view and the controller. The form backing object is typically a POJO (Plain Old Java Object) with properties that correspond to the form fields.
Example:
public class User { private String name; private String email; // Getters and setters }
Validation in Spring MVC is typically done using JSR-303/JSR-380 (Bean Validation API) annotations and a validator implementation. Spring provides support for validating form backing objects using these annotations and the @Valid or @Validated annotation in controller methods.
Example:
Form Backing Object with validation annotations:
import javax.validation.constraints.Email; import javax.validation.constraints.NotEmpty; public class User { @NotEmpty(message = "Name is required") private String name; @Email(message = "Email should be valid") @NotEmpty(message = "Email is required") private String email; // Getters and setters }
Controller method with @Valid:
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import javax.validation.Valid; @Controller public class UserController { @GetMapping("/userForm") public String showForm(Model model) { model.addAttribute("user", new User()); return "userForm"; } @PostMapping("/userForm") public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult result) { if (result.hasErrors()) { return "userForm"; } // Process the form submission return "success"; } }
BindingResult is an interface provided by Spring that holds the results of the validation and binding of form backing objects. It contains information about validation errors and can be used to determine whether the form submission is valid.
Example:
@PostMapping("/userForm") public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult result) { if (result.hasErrors()) { return "userForm"; } // Process the form submission return "success"; }
Validation results are automatically mapped to the view using the BindingResult object. The view can then access the error messages through the Spring form tags.
Example (JSP):
<form:form modelAttribute="user" method="post"> <form:errors path="*" cssClass="error" /> <div> <form:label path="name">Name:</form:label> <form:input path="name" /> <form:errors path="name" cssClass="error" /> </div> <div> <form:label path="email">Email:</form:label> <form:input path="email" /> <form:errors path="email" cssClass="error" /> </div> <input type="submit" value="Submit" /> </form:form>
Spring form tags are a set of JSP tags provided by the Spring Framework to simplify the development of web forms. These tags bind form fields to form backing objects, making it easier to handle form data and validation errors.
Common Spring Form Tags:
Example:
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <h2>User Form</h2> <form:form modelAttribute="user" method="post"> <div> <form:label path="name">Name:</form:label> <form:input path="name" /> <form:errors path="name" cssClass="error" /> </div> <div> <form:label path="email">Email:</form:label> <form:input path="email" /> <form:errors path="email" cssClass="error" /> </div> <input type="submit" value="Submit" /> </form:form> </body> </html>
Summary:
A Path Variable in Spring MVC is used to extract values from the URI of a web request. It allows you to capture dynamic values from the URI and use them in your controller methods.
Example:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @RequestMapping(value = "/user/{id}", method = RequestMethod.GET) @ResponseBody public String getUserById(@PathVariable("id") String userId) { return "User ID: " + userId; } }
In this example, if a request is made to /user/123, the method getUserById will capture 123 as the userId parameter.
A Model Attribute in Spring MVC is used to bind a method parameter or a return value to a named model attribute, which can be accessed in the view. It is typically used to prepare data for rendering in the view.
Example:
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class MyController { @RequestMapping(value = "/form", method = RequestMethod.GET) public String showForm(Model model) { model.addAttribute("user", new User()); return "userForm"; } @RequestMapping(value = "/form", method = RequestMethod.POST) public String submitForm(@ModelAttribute User user) { // Process form submission return "result"; } }
In this example, the User object is added to the model and made available to the view (userForm.jsp). When the form is submitted, the User object is populated with the form data and processed in the submitForm method.
A Session Attribute in Spring MVC is used to store model attributes in the HTTP session, allowing them to persist across multiple requests. This is useful for maintaining state between requests.
Example:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.SessionAttributes; @Controller @SessionAttributes("user") public class MyController { @RequestMapping(value = "/form", method = RequestMethod.GET) public String showForm(Model model) { model.addAttribute("user", new User()); return "userForm"; } @RequestMapping(value = "/form", method = RequestMethod.POST) public String submitForm(@ModelAttribute User user) { // Process form submission return "result"; } @RequestMapping(value = "/clearSession", method = RequestMethod.GET) public String clearSession(SessionStatus status) { status.setComplete(); return "sessionCleared"; } }
In this example, the User object is stored in the session and can be accessed across multiple requests. The clearSession method can be used to clear the session attributes.
Summary:
An Init Binder in Spring MVC is a mechanism that allows you to customize the way data is bound to the form backing objects. It is used to initialize WebDataBinder, which performs data binding from web request parameters to JavaBean objects. @InitBinder methods are used to register custom editors, formatters, and validators for specific form fields or types.
Scenario: You have a form that includes a date field and you want to use a specific date format.
public class User { private String name; private Date birthDate; // Getters and setters }
import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import java.text.SimpleDateFormat; import java.util.Date; @Controller public class UserController { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } @RequestMapping(value = "/form", method = RequestMethod.GET) public String showForm(Model model) { model.addAttribute("user", new User()); return "userForm"; } @RequestMapping(value = "/form", method = RequestMethod.POST) @ResponseBody public String submitForm(@ModelAttribute User user) { // Process form submission return "Name: " + user.getName() + ", Birth Date: " + user.getBirthDate(); } }
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <h2>User Form</h2> <form:form modelAttribute="user" method="post"> <div> <form:label path="name">Name:</form:label> <form:input path="name" /> </div> <div> <form:label path="birthDate">Birth Date (yyyy-MM-dd):</form:label> <form:input path="birthDate" /> </div> <input type="submit" value="Submit" /> </form:form> </body> </html>
Summary:
This customization allows precise control over how form data is converted and validated before it is bound to the controller's method parameters.
To set a default date format in a Spring application, you typically use an @InitBinder method in your controller to register a custom date editor. This approach allows you to specify the date format that should be used for all date fields in your form backing objects.
Here is a detailed example:
Create a simple Java class to represent your form data.
public class User { private String name; private Date birthDate; // Getters and setters public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } }
Create a Spring MVC controller with an @InitBinder method to register the custom date editor.
import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.text.SimpleDateFormat; import java.util.Date; @Controller public class UserController { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } @RequestMapping(value = "/form", method = RequestMethod.GET) public String showForm(Model model) { model.addAttribute("user", new User()); return "userForm"; } @RequestMapping(value = "/form", method = RequestMethod.POST) public String submitForm(@ModelAttribute User user, Model model) { // Process form submission model.addAttribute("user", user); return "result"; } }
Create a JSP file for the form (e.g., userForm.jsp).
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <h2>User Form</h2> <form:form modelAttribute="user" method="post"> <div> <form:label path="name">Name:</form:label> <form:input path="name" /> </div> <div> <form:label path="birthDate">Birth Date (yyyy-MM-dd):</form:label> <form:input path="birthDate" /> </div> <input type="submit" value="Submit" /> </form:form> </body> </html>
Create another JSP file to display the result (e.g., result.jsp).
<html> <body> <h2>Form Submitted</h2> <p>Name: ${user.name}</p> <p>Birth Date: ${user.birthDate}</p> </body> </html>
This approach ensures that all date fields in your form backing objects use the specified date format ("yyyy-MM-dd" in this example), simplifying date handling and validation in your Spring application.
Exception handling in Spring MVC can be done in various ways, from using traditional try-catch blocks to leveraging Spring's @ExceptionHandler and @ControllerAdvice annotations for a more centralized and sophisticated approach.
You can handle exceptions locally within a controller by using the @ExceptionHandler annotation. This annotation is used to define a method that will handle exceptions thrown by request handling methods in the same controller.
Example:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @RequestMapping(value = "/test", method = RequestMethod.GET) public String test() { if (true) { throw new RuntimeException("Test exception"); } return "test"; } @ExceptionHandler(RuntimeException.class) @ResponseBody public String handleRuntimeException(RuntimeException ex) { return "Handled RuntimeException: " + ex.getMessage(); } }
For a more global approach to exception handling, you can use @ControllerAdvice. This annotation allows you to define a class that will handle exceptions for all controllers or specific controllers.
Example:
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(RuntimeException.class) @ResponseBody public String handleRuntimeException(RuntimeException ex) { return "Handled by GlobalExceptionHandler: " + ex.getMessage(); } @ExceptionHandler(Exception.class) public ModelAndView handleException(Exception ex) { ModelAndView mav = new ModelAndView("error"); mav.addObject("message", ex.getMessage()); return mav; } }
In this example, GlobalExceptionHandler will handle RuntimeException and Exception globally for all controllers in the application.
Local Exception Handling:
Global Exception Handling:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/api") public class MyApiController { @GetMapping("/test") @ResponseBody public String test() { if (true) { throw new RuntimeException("Test exception in API"); } return "test"; } }
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(RuntimeException.class) @ResponseBody public String handleRuntimeException(RuntimeException ex) { return "Handled by GlobalExceptionHandler: " + ex.getMessage(); } @ExceptionHandler(Exception.class) public ModelAndView handleException(Exception ex) { ModelAndView mav = new ModelAndView("error"); mav.addObject("message", ex.getMessage()); return mav; } }
In this setup:
Exception Handling in Controllers:
Global Exception Handling with @ControllerAdvice:
Use Cases:
Spring MVC 流行有以下幾個原因:
簡單:Spring MVC 提供了一種創建 Web 應用程式的簡單方法,只需最少的配置。
模組化:它允許採用模組化方法進行設計,這使得維護和更新程式碼變得更加容易。
整合:Spring MVC 可以輕鬆與其他流行的 Java 框架(如 Hibernate、JPA 等)整合
可測試性:為測試提供了出色的支持,可以更輕鬆地保證應用程式的品質。
社區支持:它擁有一個龐大且活躍的社區,這意味著可以隨時獲得幫助。
多功能性:它可用於開發各種應用程序,從簡單的網站到複雜的企業應用程式。
文檔:有豐富詳細的文檔,方便學習和使用。
以上是Spring MVC 面試問問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!