Spring学习 基础(三)MVC

5、Spring MVC

传统Web模式:

  1. Model:系统涉及的数据,也就是 dao 和 bean。
  2. View:展示模型中的数据,只是用来展示。
  3. Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。

img

随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。

Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。

组件:
  • DispatcherServlet核心的中央处理器,负责接收请求、分发,并给予客户端响应。
  • HandlerMapping处理器映射器,根据 uri 去匹配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。
  • HandlerAdapter处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler;
  • Handler请求处理器,处理实际请求的处理器。
  • ViewResolver视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端
流程:
  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。
  2. DispatcherServlet 根据请求信息调用 HandlerMapping 。HandlerMapping 根据 uri 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。
  3. DispatcherServlet 调用 HandlerAdapter适配执行 Handler 。
  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给DispatcherServlet,ModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。Model 是返回的数据对象,View 是个逻辑上的 View。
  5. ViewResolver 会根据逻辑 View 查找实际的 View。
  6. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
  7. 把 View 返回给请求者(浏览器)

原理.png

层次结构
  1. Model 层(Model)
  • 数据访问对象(Data Access Object, DAO):与数据库的交互,负责提供数据操作的方法。
  • 服务层(Service Layer):封装业务逻辑,进行事务管理。
  • 数据传输对象(Data Transfer Object, DTO):在各层之间传输数据。
  1. 视图层(View)
  • 视图技术:如 JSP、FreeMarker、Thymeleaf 等,用来渲染界面。
  • 静态资源:如 HTML、CSS、JavaScript 文件。
  1. 控制层(Controller)
  • DispatcherServlet: 作为前端控制器,所有的请求都会先经过它。它负责将请求路由到相应的处理器,并处理其他如多视图解析、国际化、主题解析等。
  • 控制器(Controllers):处理用户请求,将请求映射到对应的处理逻辑,并返回响应或视图名给前端。
  • 表单对象(Form Object)/命令对象(Command Object):封装客户端提交数据。

除了这三个主要层次外,在实际的Spring MVC应用中,还可能有以下组件或层次:

  1. Web 层
  • 过滤器(Filters):进行请求的预处理和响应的后处理。
  • 拦截器(Interceptors):在控制器执行前后或视图渲染前执行特定逻辑。
  1. 配置层
  • 配置类或XML文件:定义 Spring Bean、数据源、事务管理器等配置信息。
  1. 安全层
  • Spring Security:提供认证和授权的机制来保护应用程序。

DTO和DAO?

  • DTO 主要用于传输跨层或跨系统边界的数据。

  • DAO 专注于提供数据访问技术的抽象,例如数据库操作。

    目的:DTO 主要用于封装从一个系统到另一个系统的数据传输,是一种简单的Java对象,它用于聚合多个数据项以便于传输。
    作用范围:DTO 通常用于服务层与控制层之间或者不同应用程序/服务之间的数据传递。DTO 的目的是减少数据交换时的网络开销,并且可以定制所需展现给客户端的数据结构。
    内容:DTO 不包含任何业务逻辑,仅包含数据字段及其getter和setter方法。有时候,DTO 也可能包含一些简单的转换逻辑或校验逻辑。
    示例:如果需要展示用户信息和他们的订单数量,可以创建一个 UserOrdersDTO 类来封装这两类信息,即使用户信息和订单数量来自不同的源头。目的:DAO 是指访问数据源的对象,它封装了对数据源CRUD(创建、检索、更新、删除)操作的实现。
    作用范围:DAO 直接与数据存储(如数据库)打交道。它抽象和封装了所有与数据持久化相关的操作,使上层业务逻辑不直接依赖于底层的数据持久化细节。
    内容:DAO 通常会提供各种方法来访问数据源,如 findById, findAll, save, update, 和 delete 等。
    示例:有一个 UserDAO 类,提供了获取用户信息、保存新用户等与用户表直接关联的数据库操作方法。
    

DispatcherServlet?

  • 请求路由DispatcherServlet 根据请求的URL来确定选择哪个控制器(Controller)进行处理,并且将请求转发给相对应的控制器。
  • 控制器选择:通过使用处理器映射(Handler Mapping)来识别URL请求所对应的控制器。
  • 调用适配器:使用处理器适配器(Handler Adapter)来执行控制器中相应的方法。
  • 模型和视图解析:控制器处理完请求后,返回一个模型和视图(ModelAndView)对象,DispatcherServlet 会根据这个对象来选择相应的视图技术进行渲染。
软件架构

在软件架构中,持久层(Persistence Layer)、业务层(Business Layer)和表示层/视图层(Presentation Layer)是三个主要的层次结构,它们各自负责不同的功能区域,并且通常相互分离,以实现关注点分离(Separation of Concerns)。以下是每一层的简单介绍:

持久层(Persistence Layer)

持久层,也称为数据访问层(Data Access Layer),负责与数据库进行交互,执行CRUD操作(创建、读取、更新、删除)。它提供了一个抽象层使得业务逻辑可以访问数据库操作所需的数据。在Java应用中,这一层可以通过使用ORM框架如Hibernate,或者使用数据访问技术如JDBC、JPA、MyBatis来实现。

业务层(Business Layer)

业务层包含应用程序的业务逻辑,其核心功能是实现应用程序的业务规则。业务层协调应用程序的工作流程,处理用户请求,并对持久层发送的数据执行业务决策。在复杂应用中,业务层可能还会处理事务、授权和其他核心功能。常见的Spring注解@Service就是用来标记业务层的组件。

表示层/视图层(Presentation Layer)

表示层是用户看到并与之交互的界面,它负责数据的展示和用户输入的处理。在Web应用中,表示层可以由HTML、CSS和JavaScript组成,而在服务器端,Spring MVC框架中的@Controller注解被用来处理HTTP请求,并返回对应的视图名称或响应体。表示层通常从业务层获取数据,并将用户输入传送到业务层进行处理。

每层都专注于其职责范围内的特定任务,从而实现了代码的模块化和清晰的架构设计。通过这种分层,开发人员能够独立地开发和测试每个层次,提高了应用程序的维护性和可扩展性。在Spring框架中,这些层通常由不同的Spring组件来实现,比如使用@Repository注解的类实现持久层,@Service注解的类实现业务层,@Controller或@RestController注解的类实现表示层。

常用Bean

特殊bean.png

<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --> ResourceViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/" /><property name="suffix" value=".jsp" />
</bean>
<!-- 上传限制 --> MultipartResolver
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 上传文件大小限制为31M,31*1024*1024 --><property name="maxUploadSize" value="32505856"/>
</bean>//当解析器MultipartResolver完成处理时,请求便会像其他请求一样被正常流程处理。@RequestMapping(path = "/form", method = RequestMethod.POST)public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) {if (!file.isEmpty()) {byte[] bytes = file.getBytes();// store the bytes somewherereturn "redirect:uploadSuccess";}return "redirect:uploadFailure";
}
统一异常处理怎么做?

使用注解的方式统一异常处理,具体会使用到 @ControllerAdvice + @ExceptionHandler 这两个注解 。这种异常处理方式下,会给所有或者指定的 Controller 织入异常处理的逻辑(AOP),当 Controller 中的方法抛出异常的时候,由被@ExceptionHandler 注解修饰的方法进行处理。

异常处理方式.png

@ExceptionHandler(Exception.class)
public Object exceptionHandler(Exception ex, HttpServletResponse response, HttpServletRequest request) throws IOException {String url = "";String msg = ex.getMessage();Object resultModel = null;try {if (ex.getClass() == HttpRequestMethodNotSupportedException.class) {url = "admin/common/500";System.out.println("--------毛有找到对应方法---------");} else if (ex.getClass() == ParameterException.class) {//自定义的异常} else if (ex.getClass() == UnauthorizedException.class) {url = "admin/common/unauth";System.out.println("--------毛有权限---------");}String header = req.getHeader("X-Requested-With");boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header);String method = req.getMethod();boolean isPost = "POST".equalsIgnoreCase(method);if (isAjax || isPost) {return Message.error(msg);} else {ModelAndView view = new ModelAndView(url);view.addObject("error", msg);view.addObject("class", ex.getClass());view.addObject("method", request.getRequestURI());return view;}} catch (Exception exception) {logger.error(exception.getMessage(), exception);return resultModel;} finally {logger.error(msg, ex);ex.printStackTrace();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/275184.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python逆向:pyc字节码转py文件

一、 工具准备 反编译工具&#xff1a;pycdc.exe 十六进制编辑器&#xff1a;010editor 二、字节码文件转换 在CTF中&#xff0c;有时候会得到一串十六进制文件&#xff0c;通过010editor使用查看后&#xff0c;怀疑可能是python的字节码文件。 三、逆向反编译 将010editor得到…

【Redis】redis持久化

redis 持久化 Redis是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免进程退出导致数据的永久丢失&#xff0c;需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘&#xff1b;当下次Redis重启时&#xff0c;利用持久化文件实现数据恢复。除此之…

前端性能优化 | CDN缓存

前言 CDN&#xff08;Content Delivery Network&#xff09;是一种分布式的网络架构&#xff0c;通过在全球各地部署节点服务器来快速传输和分发网络内容。CDN的主要目标是提供快速、可靠的内容传输&#xff0c;以提升用户体验。 本文主要从以下方面讲解CDN 什么是CDNCDN的作…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的木材表面缺陷检测系统(深度学习+Python代码+UI界面+训练数据集)

摘要&#xff1a;开发高效的木材表面缺陷检测系统对于提升木材加工行业的质量控制和生产效率至关重要。本篇博客详细介绍了如何运用深度学习技术构建一个木材表面缺陷检测系统&#xff0c;并提供了完整的实现代码。该系统采用了强大的YOLOv8算法&#xff0c;并对YOLOv7、YOLOv6…

十六、接口隔离原则、反射、依赖注入

接口隔离原则、反射、特性、依赖注入 接口隔离原则 客户端不应该依赖它不需要的接口&#xff1b;一个类对另一个类的依赖应该建立在最小的接口上。 五种原则当中的i 上一章中的接口&#xff0c;即契约。 契约就是在说两件事&#xff0c;甲方说自己不会多要&#xff0c;乙方会在…

如何轻松打造属于自己的水印相机小程序?

水印相机小程序源码 描述&#xff1a;微信小程序。本文将为您详细介绍小程序水印相机源码的搭建过程&#xff0c;教您如何轻松打造属于自己的水印相机小程序。无论您是初学者还是有一定基础的开发者&#xff0c;都能轻松掌握这个教程。 一&#xff1a;水印相机搭建教程 1 隐…

JS ATM练习案例(复习循环知识)

需求&#xff1a;用户可以选择存钱、取钱、查看余额和退出功能。 分析&#xff1a;1循环时反复出现提示框&#xff0c;所以提示框写到循环里面。 2.退出的条件是4&#xff0c;所以是4就会结束循环 3.提前准备一个金额预存储 4取钱为减法操作&#xff0c;存钱为加法操作&#xf…

【Linux】-Linux下的软件商店yum工具介绍(linux和windows互传文件仅仅一个拖拽搞定!!!!)

目录 1.Linux 软件包管理器yum 1.1快速认识yum 1.2 yumz下载方式&#xff08;如何使用yum进行下载&#xff0c;注意下载一定要是root用户或者白名单用户&#xff08;可提权&#xff09;&#xff09; 1.2.1下载小工具rzsz 1.2.2 rzsz使用 1.2.2查看软件包 1.3软件的卸载 2.yum生…

【考研数学】打基础用张宇《30讲》还是武忠祥《基础篇》?

基础课不太可能所有的东西全都覆盖&#xff0c;还是先搭起一个知识框架&#xff0c;然后不断的填充和完善。 所以不必太过于在意少一些东西&#xff0c;我们不可能一口吃成胖子&#xff0c;基础知识肯定不会遗漏的&#xff0c;只可能一些技巧不到位。 从自己的情况考虑&#…

(BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等

看面试题可以是为了面试&#xff0c;也可以是对自己学到的东西的一种查漏补缺&#xff0c;更加深刻的去了解一些核心知识点 Spring面试高频问题 问题一&#xff1a;谈 需要zi料 绿色徽【vip1024b】 谈你对spring IOC 和 DI 的理解&#xff0c;它们有什么区别&#xff1f; **问题…

一文掌握mysql中的查询语句

目录 1. 聚合查询1.1 聚合函数1.2 GROUP BY子句1.3 HAVING 2. 联合查询2.1 内连接2.2 外连接2.3 自连接2.4 子查询2.5 合并查询 1. 聚合查询 1.1 聚合函数 常见的统计总数、计算平局值等操作&#xff0c;可以使用聚合函数来实现&#xff0c;常见的聚合函数有&#xff1a; 函…

Autosar教程-Mcal教程-GPT配置教程

3.3GPT配置、生成 3.3.1 GPT配置所需要的元素 GPT实际上就是硬件定时器,需要配置的元素有: 1)定时器时钟:定时器要工作需要使能它的时钟源 2)定时器分步:时钟源进到定时器后可以通过分频后再给到定时器 定时器模块选择:MCU有多个定时器模块,需要决定使用哪个定时器模块作…

【Web】浅聊XStream反序列化本源之恶意动态代理注入

目录 简介 原理 复现 具体分析之前 我们反序列化了个什么&#xff1f; XStream反序列化的朴素通识 具体分析 第一步&#xff1a;unmarshal解组 第二步&#xff1a;readClassType获取动态代理类的Class对象 第三步&#xff1a;调用convertAnother对动态代理类进行实例…

【阿里云系列】-基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户&#xff0c;我们通常会选择CICD工具来减少人力投入产生的成本&#xff0c;开源的工具比如有成熟的Jenkins&#xff0c;但是本文讲的是阿里云提高的解决方案云效平台&#xff0c;通过配置流水线的形式实现项目的快速部署到服务器…

c++0305习题

一、求下面表达式的值 1&#xff0e;0 2&#xff0e;-1 3&#xff0e;1 4&#xff0e;&#xff08;1&#xff09;1 &#xff08;2&#xff09;3.2 &#xff08;3&#xff09;0 &#xff08;4&#xff09;7.0 5.&#xff08;1&#xff09;0&#xff08;2&#xff09;300.005&a…

Codeforces Round 933 (Div. 3) A~D

比赛链接 : codeforces.com/contest/1941 A . Rudolf and the Ticket 直接暴力即可 ; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \n #define lowbit(x) (x&(-x)) #define sz(a) (int)a.size() #define p…

蓝桥杯之【01背包模版】牛客例题展示

牛客链接 #include <bits/stdc.h> using namespace std; int n,V; const int N1010; int v[N],w[N]; int dp[N][N]; int main() {cin>>n>>V;for(int i1;i<n;i){cin>>v[i]>>w[i];}for(int i1;i<n;i){for(int j1;j<V;j){dp[i][j]dp[i-1][…

30天学会QT(进阶)--------------第二天(创建项目)

1、如何规范的创建一个项目 由于本人也是从其他的项目上学来的&#xff0c;所以也不算是业界规范&#xff0c;每个公司或者个人都有自己的方式去创建项目&#xff0c;项目的创建是本着简洁&#xff0c;明了&#xff0c;方便而言的&#xff0c;所以对于我来说&#xff0c;不繁琐…

力扣大厂热门面试算法题 21-23

21. 合并两个有序链表&#xff0c;22. 括号生成&#xff0c;23. 合并 K 个升序链表&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.13 可通过leetcode所有测试用例。 目录 21. 合并两个有序链表 解题思路 完整代码 Java Py…

linuxOPS基础_vmware虚拟机安装及介绍

虚拟机概念 什么是虚拟机&#xff1f; 虚拟机&#xff0c;有些时候想模拟出一个真实的电脑环境&#xff0c;碍于使用真机安装代价太大&#xff0c;因此而诞生的一款可以模拟操作系统运行的软件。 虚拟机目前有2 个比较有名的产品&#xff1a;vmware 出品的vmware workstatio…