Spring学习 基础(三)MVC

news2025/2/26 18:09:46
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 somewhere
          return "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.coloradmin.cn/o/1504787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】time库知识整理

简介 python的time库是python内置库&#xff0c;主要负责处理与时间相关的事务。 获取当前时间 函数作用time()获取当前时间戳ctime()获取字符串形式的时间gmtime()调用内部方法&#xff0c;赋予属性&#xff0c;能够被程序调用执行 time返回的是时间戳 ctime是返回的我们…

智慧安防视频远程监控平台EasyCVR集成后播放只有一帧画面是什么原因?

智慧安防视频监控平台EasyCVR能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台可支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议…

Linux网络套接字之预备知识

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 目录 一、预备知识 1.理解源IP地址和目的IP地址 …

Day27:安全开发-PHP应用TP框架路由访问对象操作内置过滤绕过核心漏洞

目录 TP框架-开发-配置架构&路由&MVC模型 TP框架-安全-不安全写法&版本过滤绕过 思维导图 PHP知识点 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框架开发等 技…

Android14之解决报错:No module named sepolgen(一百九十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

excel统计分析——嵌套设计

参考资料&#xff1a;生物统计学&#xff0c;巢式嵌套设计的方差分析 嵌套设计&#xff08;nested design&#xff09;也称为系统分组设计或巢式设计&#xff0c;是把试验空间逐级向低层次划分的试验设计方法。与裂区设计相似&#xff0c;先按一级因素设计试验&#xff0c;然后…

LeetCode-1004. 最大连续1的个数 III

每日一题系列&#xff08;day 20&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50…

【OpenCV】如何在Linux操作系统下正确安装 OpenCV

前言 我是在虚拟机上跑的 Linux 5.8.0-44-generic。 配置如下&#xff1a; 目录 第一步&#xff1a;下载依赖文件 第二步&#xff1a;下载 opencv 和 opencv_contrib 源码 第三步&#xff1a;解压缩包 第四步&#xff1a;移动文件 第五步&#xff1a;生成 makefile 文件 …

oracle基础-多表关联查询 备份

一、概述 在实际应用系统开发中会设计多个数据表&#xff0c;每个表的信息不是独立存在的&#xff0c;而是若干个表之间的信息存在一定的关系&#xff0c;当用户查询某一个表的信息时&#xff0c;很可能需要查询关联数据表的信息&#xff0c;这就是多表关联查询。SELECT语句自身…

Prometheus添加nginx节点显示不支持stub_status 解决办法

1、我们在使用Prometheus监控添加nginx节点监控的时候&#xff0c;在被监控节点的nginx配置文件中添加下面的模块 server { listen 80; server_name localhost; location /stub_status { stub_status on; access_log off; …

【解读】OWASP 大语言模型(LLM)安全测评基准V1.0

大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数&#xff0c;使得它们能够处理更复杂的问题&#xff0c;并学习更广泛的知识。自2022 年以来&#xff0c;LLM技术在得到了广泛的应…

网络触手获取天气数据存入mysql 项目

首先这个案例不一定能直接拿来用&#xff0c;虽然我觉得可以但是里面肯定有一些我没考虑到的地方。 有问题评论或者私信我&#xff1a; 这个案例适合我这种学生小白 获取天气数据网址&#xff1a; https://lishi.tianqi.com/xianyang/202201.html 网络触手获取天气数据代码直…

这是一段神奇的提示词,能直接调取Claude 3的系统提示词!附详细解读

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

第一代高通S7和S7 Pro音频平台:超旗舰性能,全面革新音频体验

以下文章来源于高通中国 如今&#xff0c;音频内容与形式日渐丰富&#xff0c;可满足人们放松心情、提升自我、获取资讯等需求。得益于手机、手表、耳机、车载音箱等智能设备的广泛应用&#xff0c;音频内容可以更快速触达用户。从《音频产品使用现状调研报告2023》中发现&…

蓝桥杯大赛软件python赛道真题:蛇形填数

真题链接&#xff1a;https://www.lanqiao.cn/problems/594/learning/ 题目描述&#xff1a; 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 如下图所示&#xff0c;小明用从1开始的正整数“蛇形”填充无限大的矩阵。 1 2 6 …

15:00面试,15:07就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到3月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

leetcode 热题 100_相交链表

题解一&#xff1a; 哈希表&#xff1a;两链表出现的第一个相同的值就是相交节点&#xff0c;因此我们先用哈希记录链表A所有出现过的值&#xff0c;再遍历链表B查找哈希表&#xff0c;找出第一个相同的值即为结果。 import java.util.HashSet;public class Solution {public …

实验二 Hello, miniEuler操作演示(保姆级教程)

PS&#xff1a;所有的批注都写在了块引用中&#xff0c;其他文字均为题干 print函数是学习几乎任何一种软件开发语言时最先学习使用的函数&#xff0c;同时该函数也是最基本和原始的程序调试手段&#xff0c;但该函数的实现却并不简单。本实验的目的在于理解操作系统与硬件的接…

DeepLearning in Pytorch|共享单车预测NN详解(思路+代码剖析)

目录 概要 一、代码概览 二、详解 基本逻辑 1.数据准备 2.设计神经网络 初版 改进版 测试 总结 概要 原文链接&#xff1a;DeepLearning in Pytorch|我的第一个NN-共享单车预测 我的第一个深度学习神经网络模型---利用Pytorch设计人工神经网络对某地区租赁单车的使用…

Diddler抓包工具——学习笔记

F12抓包 302【重定向】&#xff1a;当你发送了一个请求之后&#xff0c;那么这个请求重定向到了另外的资源 跳转和重定向的区别&#xff1a; 跳转是会把数据传到新的地址 重定向不会把新的数据传到新的地址 使用F12抓包时一定要打开Preserve Log开关&#xff0c;作用是保留…