Spring MVC深度解析從原理到實(shí)戰(zhàn)(最新推薦)
一、Spring MVC概述
1.1 MVC設(shè)計(jì)模式
MVC(Model-View-Controller)是一種經(jīng)典的軟件架構(gòu)模式,將應(yīng)用程序分為三個(gè)核心組件:
- Model:數(shù)據(jù)模型,負(fù)責(zé)業(yè)務(wù)邏輯和數(shù)據(jù)管理
- View:視圖層,負(fù)責(zé)數(shù)據(jù)展示
- Controller:控制器,處理用戶請(qǐng)求并協(xié)調(diào)Model和View
1.2 Spring MVC特點(diǎn)
- 基于DispatcherServlet的前端控制器模式
- 靈活的配置方式(注解驅(qū)動(dòng))
- 強(qiáng)大的數(shù)據(jù)綁定和驗(yàn)證機(jī)制
- 支持多種視圖技術(shù)(JSP、Thymeleaf等)
- 與Spring框架無(wú)縫集成
二、Spring MVC核心組件
2.1 架構(gòu)流程圖解
[客戶端] --> [DispatcherServlet] --> [HandlerMapping] --> [Controller] --> [ModelAndView] --> [ViewResolver] --> [視圖]
2.2 核心組件說(shuō)明
- DispatcherServlet:前端控制器,統(tǒng)一處理請(qǐng)求
- HandlerMapping:請(qǐng)求到處理器的映射
- Controller:業(yè)務(wù)邏輯處理器
- ViewResolver:視圖解析器
- HandlerAdapter:處理器適配器
- Model:數(shù)據(jù)模型容器
三、環(huán)境搭建與配置
3.1 Maven依賴
<dependencies> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <!-- Servlet API --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies>
3.2 傳統(tǒng)XML配置 vs JavaConfig
XML配置示例:
<!-- web.xml --> <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-mvc.xml</param-value> </init-param> </servlet>
JavaConfig實(shí)現(xiàn):
@Configuration @EnableWebMvc @ComponentScan("com.example.controller") public class WebConfig implements WebMvcConfigurer { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } }
四、控制器開發(fā)實(shí)踐
4.1 基礎(chǔ)控制器示例
@Controller @RequestMapping("/user") public class UserController { @GetMapping("/profile") public String showProfile(Model model) { User user = userService.getCurrentUser(); model.addAttribute("user", user); return "profile"; } @PostMapping("/update") public String updateProfile(@Valid UserForm form, BindingResult result) { if (result.hasErrors()) { return "edit-profile"; } userService.updateUser(form); return "redirect:/user/profile"; } }
4.2 請(qǐng)求映射注解
@RequestMapping
:通用請(qǐng)求映射@GetMapping
/@PostMapping
:特定HTTP方法映射@PathVariable
:URL模板變量@RequestParam
:請(qǐng)求參數(shù)綁定
@GetMapping("/articles/{id}") public String getArticle(@PathVariable Long id, @RequestParam(defaultValue = "desc") String sort, Model model) { // 業(yè)務(wù)邏輯 return "article-detail"; }
五、數(shù)據(jù)處理與綁定
5.1 表單處理示例
@Controller @RequestMapping("/product") public class ProductController { @GetMapping("/create") public String showForm(Model model) { model.addAttribute("product", new Product()); return "product-form"; } @PostMapping("/save") public String saveProduct(@ModelAttribute("product") Product product, BindingResult result) { if (result.hasErrors()) { return "product-form"; } productService.save(product); return "redirect:/product/list"; } }
5.2 數(shù)據(jù)驗(yàn)證
public class Product { @NotBlank(message = "產(chǎn)品名稱不能為空") @Size(max = 50, message = "名稱長(zhǎng)度不能超過(guò)50字符") private String name; @Min(value = 0, message = "價(jià)格不能為負(fù)數(shù)") private BigDecimal price; // getters/setters }
六、視圖技術(shù)集成
6.1 Thymeleaf配置
@Configuration @EnableWebMvc public class ThymeleafConfig { @Bean public SpringResourceTemplateResolver templateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".html"); resolver.setTemplateMode("HTML5"); resolver.setCharacterEncoding("UTF-8"); return resolver; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); return engine; } }
6.2 JSP視圖示例
<%@ page contentType="text/html;charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>用戶列表</title> </head> <body> <h2>用戶列表</h2> <table> <tr> <th>ID</th> <th>用戶名</th> <th>郵箱</th> </tr> <c:forEach items="${users}" var="user"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.email}</td> </tr> </c:forEach> </table> </body> </html>
七、RESTful API開發(fā)
7.1 REST控制器
@RestController @RequestMapping("/api/users") public class UserApiController { @Autowired private UserService userService; @GetMapping public ResponseEntity<List<User>> getAllUsers() { return ResponseEntity.ok(userService.findAll()); } @GetMapping("/{id}") public ResponseEntity<User> getUserById(@PathVariable Long id) { return userService.findById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @PostMapping public ResponseEntity<User> createUser(@RequestBody @Valid User user) { User savedUser = userService.save(user); return ResponseEntity.created(URI.create("/api/users/" + savedUser.getId())) .body(savedUser); } }
八、高級(jí)特性
8.1 攔截器實(shí)現(xiàn)
public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getSession().getAttribute("user") == null) { response.sendRedirect("/login"); return false; } return true; } } // 注冊(cè)攔截器 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login", "/register"); } }
8.2 全局異常處理
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse(); error.setTimestamp(LocalDateTime.now()); error.setStatus(HttpStatus.NOT_FOUND.value()); error.setMessage(ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorResponse> handleValidationException( MethodArgumentNotValidException ex) { List<String> errors = ex.getBindingResult() .getFieldErrors() .stream() .map(FieldError::getDefaultMessage) .collect(Collectors.toList()); ErrorResponse error = new ErrorResponse(); error.setStatus(HttpStatus.BAD_REQUEST.value()); error.setMessage("Validation failed"); error.setDetails(errors); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); } }
九、最佳實(shí)踐建議
遵循分層架構(gòu)原則:
- Controller層保持精簡(jiǎn)
- 業(yè)務(wù)邏輯放在Service層
- 數(shù)據(jù)訪問(wèn)使用Repository模式
使用DTO進(jìn)行數(shù)據(jù)傳輸:
public class UserDTO { private String username; private String email; // 省略getter/setter } @PostMapping public ResponseEntity<User> createUser(@RequestBody UserDTO dto) { User user = userConverter.convertToEntity(dto); // ... }
性能優(yōu)化建議:
- 合理使用緩存(@Cacheable)
- 啟用GZIP壓縮
- 異步處理(@Async)
安全注意事項(xiàng):
- 使用CSRF保護(hù)
- 輸入驗(yàn)證和輸出編碼
- 參數(shù)化查詢防止SQL注入
十、常見(jiàn)問(wèn)題排查
404錯(cuò)誤排查步驟:
- 檢查@RequestMapping注解路徑
- 確認(rèn)視圖解析器配置
- 查看組件掃描范圍
數(shù)據(jù)綁定失敗處理:
- 檢查字段名稱是否匹配
- 驗(yàn)證數(shù)據(jù)類型是否兼容
- 使用@InitBinder進(jìn)行自定義綁定
性能問(wèn)題分析:
- 使用Spring Actuator監(jiān)控端點(diǎn)
- 分析數(shù)據(jù)庫(kù)查詢性能
- 檢查視圖渲染時(shí)間
到此這篇關(guān)于Spring MVC深度解析:從原理到實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)Spring MVC原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springmvc ModelAndView原理及用法詳解
- SpringMVC Mock測(cè)試實(shí)現(xiàn)原理及實(shí)現(xiàn)過(guò)程詳解
- Springmvc數(shù)據(jù)回顯實(shí)現(xiàn)原理實(shí)例解析
- SpringMvc自動(dòng)裝箱及GET請(qǐng)求參數(shù)原理解析
- SpringMVC MVC架構(gòu)原理及實(shí)現(xiàn)方法詳解
- SpringMVC文件上傳原理及實(shí)現(xiàn)過(guò)程解析
- Spring MVC數(shù)據(jù)綁定概述及原理詳解
- SpringMVC體系分層模式原理圖解
- SpringMVC注解@RequestParam方法原理解析
- SpringMVC工作原理實(shí)例詳解
相關(guān)文章
詳解java接口(interface)在不同JDK版本中的變化
這篇文章主要介紹了詳解java接口(interface)在不同JDK版本中的變化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Java多態(tài)用法與注意點(diǎn)實(shí)例分析
這篇文章主要介紹了Java多態(tài)用法與注意點(diǎn),結(jié)合實(shí)例形式分析了java多態(tài)相關(guān)的向上轉(zhuǎn)型、向下轉(zhuǎn)型、隱藏等相關(guān)操作技巧,需要的朋友可以參考下2019-08-08startJVM錯(cuò)誤Unable to load native library: libjvm.so解決方法
這篇文章主要介紹了startJVM錯(cuò)誤Unable to load native library: libjvm.so解決方法,需要的朋友可以參考下2014-07-07Java中Lambda表達(dá)式和函數(shù)式接口的使用和特性
Java Lambda表達(dá)式是一種函數(shù)式編程的特性,可簡(jiǎn)化匿名內(nèi)部類的寫法,與函數(shù)式接口搭配使用,實(shí)現(xiàn)代碼簡(jiǎn)潔、可讀性高、易于維護(hù)的特點(diǎn),適用于集合操作、多線程編程等場(chǎng)景2023-04-04springboot模塊里面調(diào)用另外一個(gè)模塊的方法實(shí)現(xiàn)
在Spring-Boot項(xiàng)目開發(fā)中,存在著本模塊的代碼需要訪問(wèn)外面模塊接口,本文就來(lái)介紹一下springboot模塊里面調(diào)用另外一個(gè)模塊的方法實(shí)現(xiàn),感興趣的可以了解一下2023-11-11SpringBoot2之PUT請(qǐng)求接收不了參數(shù)的解決方案
這篇文章主要介紹了SpringBoot2之PUT請(qǐng)求接收不了參數(shù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07java通過(guò)控制鼠標(biāo)實(shí)現(xiàn)屏幕廣播的方法
這篇文章主要介紹了java通過(guò)控制鼠標(biāo)實(shí)現(xiàn)屏幕廣播的方法,針對(duì)前面一篇Java屏幕共享功能進(jìn)行了改進(jìn),實(shí)現(xiàn)了鼠標(biāo)控制功能,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(1)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07IDEA下因Lombok插件產(chǎn)生的Library source does not match the bytecode報(bào)
這篇文章主要介紹了IDEA下因Lombok插件產(chǎn)生的Library source does not match the bytecode報(bào)錯(cuò)問(wèn)題及解決方法,親測(cè)試過(guò)好用,需要的朋友可以參考下2020-04-04