当前位置: 首页 > ai >正文

Spring MVC详解

目录

Spring Mvc了解

Model1时代

Model2时代

Spring MVC时代

Spring MVC注解

统一异常处理

Spring Mvc了解

MVC是模型(Model)视图(View)控制器(Controller)的简写其核心思想是通过将业务逻辑,数据显示分离来组织代码。

Model1时代

很多学Java后端比较晚的朋友可能并没有接触过Model1时代下的JavaWeb应用开发。在Model模式下,整个Web应用几乎全部用JSP页面组成,只用少量的JavaBean来处理数据连接,访问等操作。

这个模式下JSP即使控制层(Controller)优势表现层(View)。显而易见,这种模式存在很多问题。比如控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;再比如前端和后端相互依赖,难以进行测试维护并且开发效率极低

Model2时代

学过Servlet并做过相关Demo的朋友应该了解Java Bean(Model)+JSP(View)+Servlet(Controller)这种开发模式,这就是早期的Java Web MVC模式。

  • Model:系统涉及的数据,也就是dao和bean。
  • View:展示模型中的数据,只是用来展示。
  • Controller:接收用户请求,并将请求发送至Model,最后返回数据给JSP并展示给用户。

Model模式下还存在很多问题,Model2的抽象和封装程度还远远不够,使用Model2进行开发时不可避免地重复造轮子,这就大大降低了程序的可维护性和复用性。

Spring MVC时代

MVC是一种设计模式,Spring MVC是一款很优秀的MVC框架。Spring MVC可以帮助我们进行更简洁的Web层的开发,并且它天生与Spring框架集成。Spring MVC下我们一般吧后端项目分为Service层(处理业务层),Dao层(数据库操作),Entity层(实体类),Controller层(控制层,返回数据给前端)。

Spring MVC核心组件

DispatcherServlet:核心的中央处理器,负责接收请求、分发,并给予客户端响应。

HandlerMapping:处理器映射器根据 URL 去匹配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。

HandlerAdapter:处理器适配器根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler;

Handler:请求处理器,处理实际请求的处理器。

ViewResolver:视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端
 

SpringMVC工作流程图

流程说明:

  • 1.客户端(浏览器)发送请求,DispatcherServlet拦截请求。
  • 2.DispatcherServlet根据请求信息调用handlerMapping。handlerMapping会根据url去查找相应的handler(也就是我们常说的Controller控制器),并会将请求涉及到的拦截器和handler一起进行封装。
  • 3.DispatcherServlet调用handlerAdapter适配器执行Handler。
  • 4.Handler完成对用户请求的处理后,会返回一个ModeldAndView对象给DispatcherServlet,ModelAndView顾名思义,包含了数据模型以及相应的视图的信息,Model是返回的数据对象,View是个逻辑上的View。
  • 5.ViewResolver会根据逻辑View查找实际的View。
  • 6.DispatcherServlet把返回的Model传给View(视图渲染)。
  • 7.把View返回给请求者(浏览器)。

上述流程是传统开发模式的工作原理。然而现在主流的开发方式是前后端分离,这种情况下Spring MVC的View概念发生一些变化。由于View通常是前端框架(Vue,React等)来处理,后端不再负责渲染页面,而是只负责提供数据,因此:

前后端分离时候,后端通常不再返回具体的视图,而是返回纯数据(通常是Json格式),由前端分组渲染和展示。

View的部分在前后端分离的场景下往往不需要设置,SpringMVC的控制器方法只需要返回数据,不再返回ModelAndView,而是直接返回数据,Spring会自动将其转换为Json格式。相应的,ViewResolver也将不再被使用。

怎么做到呢?

使用@RestController注解代替传统的@Controller注解,这样所有方法默认会返回Json格式的数据,而不是视图解析视图。

如果你使用@Controller,可以结合@ResponseBody注解来返回Json。

Spring MVC注解

@Controller 声明Controller组件,通常作用在控制层(如 Spring MVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


@Service 声明Service组件 @Service(“myMovieLister”) ,通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Repository 声明Dao组件,将数据访问层(DAO 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


@Component 泛指组件, 可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。

@RequestMapping("/menu") 请求映射,用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@Resource 用于注入,( j2ee提供的 ) 默认按名称装配, @Resource(name=“beanName”)

@Autowired 用于注入,(srping提供的) 默认按类型装配

@Transactional( rollbackFor={Exception.class}) 事务管理

@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。

@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。

@Scope(“prototype”) 设定bean的作用域

@GetMapping:它是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式,只能处理 Get 类型请求。

@PostMapping: 它是@RequestMapping(method =RequestMethod.POST) 的一个快捷方式,只能处理 Post 类型请求。

@RequestParam :将请求参数绑定到控制器的方法参数上

@Configuration:声明当前类为配置类,相当于 xml 形式的 Spring 配置中的,该注解需要添加到类上。

统一异常处理

在使用统一异常处理的时候,具体会使用到@ControllerAdvice+@ExceptionHandler这两个注解。

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {@ExceptionHandler(BaseException.class)public ResponseEntity<?> handleAppException(BaseException ex, HttpServletRequest request) {//......}@ExceptionHandler(value = ResourceNotFoundException.class)public ResponseEntity<ErrorReponse> handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) {//......}
}

 这种异常处理方式下,会给所有或者指定的Controller织入异常处理的逻辑(AOP),当Controller中的方法抛出异常的回收,由被@ExceptionHandler注解修饰的方法进行处理。

ExceptionHandlerMethodResolver中getMappedMethod方法决定了异常具体被@ExceptionHandler注解修饰的方法处理异常。

@Nullableprivate Method getMappedMethod(Class<? extends Throwable> exceptionType) {List<Class<? extends Throwable>> matches = new ArrayList<>();//找到可以处理的所有异常信息。mappedMethods 中存放了异常和处理异常的方法的对应关系for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {if (mappedException.isAssignableFrom(exceptionType)) {matches.add(mappedException);}}// 不为空说明有方法处理异常if (!matches.isEmpty()) {// 按照匹配程度从小到大排序matches.sort(new ExceptionDepthComparator(exceptionType));// 返回处理异常的方法return this.mappedMethods.get(matches.get(0));}else {return null;}}

 解读代码

1.匹配逻辑的逆向语义

if (mappedException.isAssignableFrom(exceptionType)) { ... }

实际含义是:判断exceptionType是否是mappedException的子类(或实现类)。例如:

若 mappedException = Exception,exceptionType = IOException,则 Exception.isAssignableFrom(IOException) 返回 true(因为 IOException 是 Exception 的子类)。
若 mappedException = IOException,exceptionType = IOException,同样返回 true(自身也满足条件)。
因此,当 exceptionType=IOException,候选列表 [Exception, IOException] 中:
两个候选都会匹配成功,因为 IOException 是 Exception 的子类,同时也是自身的子类。

2.排序后的优先级

代码通过ExceptionDepathCompartor对匹配的异常类型进行排序,优先选择继承层级更近的异常。例如:

IOException与Exception的继承关系为:IOException extends Exception。

IOException 距自身(深度为0)比Exception(深度为1)更近,因此排序后IOException会排在前面。

最终返回的方法是IOException对应处理方法。

http://www.xdnf.cn/news/14751.html

相关文章:

  • windows系统下将Docker Desktop安装到除了C盘的其它盘中
  • 力扣 hot100 Day32
  • 毫米波雷达 – 深度学习
  • 腾讯 iOA 零信任产品:安全远程访问的革新者
  • 【仿muduo库实现并发服务器】Channel模块
  • Wireshark TS | 诡异的光猫网络问题
  • rocketmq 之 阿里云转本地部署实践总结
  • MySQL MVCC 详解
  • Linux基本命令篇 —— grep命令
  • jQuery UI 安装使用教程
  • 设置linux静态IP
  • 苹果AR/VR头显路线图曝光,微美全息推进AI/AR智能眼镜新品开启视觉体验篇章
  • 《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
  • 为什么js是单线程?
  • 应用场景全解析:飞算 JavaAI 的实战舞台
  • 使用vue开发浏览器chrome插件教程,及之间的消息通信
  • Rust征服字节跳动:高并发服务器实战
  • HarmonyOS应用开发高级认证知识点梳理 (三)状态管理V2装饰器核心规则
  • 端到端 pluto 之数据预处理
  • js代码09
  • 飞算JavaAI—AI编程助手 | 编程领域的‘高科技指南针’,精准导航开发!
  • 边缘人工智能与医疗AI融合发展路径:技术融合与应用前景(下)
  • 计算机网络第一章——计算机网络体系结构
  • PHP安装使用教程
  • 华为云Flexus+DeepSeek征文|​​华为云ModelArts Studio大模型 + WPS:AI智能PPT生成解决方案​
  • 设计模式-观察者模式(发布订阅模式)
  • 如何让宿主机完全看不到Wi-Fi?虚拟机独立联网隐匿上网实战!
  • 百度文心大模型4.5系列正式开源,开源会给百度带来什么?
  • 华为云Flexus+DeepSeek征文 | ​​华为云ModelArts Studio大模型与企业AI会议纪要场景的对接方案
  • 深度学习04 卷积神经网络CNN