热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringMVC基础篇:MVC基础知识

第一章:SpringMVC引言一:什么是SpringMVC概念:SpringMVC是在Spring框架基础上衍生而来的一个MVC框架&




第一章:SpringMVC引言

一:什么是SpringMVC

概念:SpringMVC是在Spring框架基础上衍生而来的一个MVC框架,主要解决了原有的MVC框架过程中控制器(Controller)的问题。
SpringMVC是Java开发当中最主流的web技术,决定了对web开发的掌握的深度。


1:什么是MVC

概念:MVC是一个架构思想,广泛应用于JavaWeb领域。

1. MVC是一个架构思想,在JavaEE开发中多用于Web开发。
2. 应用MVC架构思想开发应用,会把一个项目划分为了3个层次,M(Model) 模型层,V(View)
视图层,C(Controller) 控制层。
View JSP
Model Service+DAO
Controller Servlet
3. MVC这种分层开发,体现了面向对象各司其职的设计思想,也更加有利于后续的项目维护(修改)
补充说明:
controller控制层:纵览全局,进行调度,他就是控制器,使用servlet
view:进行相关展示,主要使用jsp进行展示,
model:业务和相关数据处理
**特定的类,只关注于特定的工作**
对于jsp来讲,他擅长的是将html和数据进行结合,进行相应的渲染,servlet来讲可以接受用户的请求,并进行相应的跳转,
这个时候,servelet适合做为控制层,service和dao完成业务的处理和数据的存储,这样三者之间是没有相互相应的,
这样的话,及时我们后续更改技术,有太大的影响,方便进行后续项目的维护

2:SpringMVC为什么要基于Spring框架


1):站在巨人的肩膀上

他基于Spring框架,就能获取Spring为我们带来的一系列的好处。Spring的牛逼之处就在于他的IOC和AOP,基于Spring也就可以大大简化MVC的开发(不必将这些优秀的功能在封装一遍)


2):独木难成桥

在Spring这个优秀的技术平台上,更加方便与其他的优秀的框架进行整合。

通过工厂(容器)创建对象,解耦合 (IOC DI)。
通过AOP的方式,为目标类(原始类),增加额外功能。
方便与第三方框架的集成:MyBatis.JPA.MQ

3:原有MVC开发中控制器


1):原有MVC开发控制器技术实现

servlet技术【Java Model2模式中提到的技术】
strus2当中的action也是控制器
Java Model2模式,是十几年前,sun公司提出的,servlet作为控制器,Jfb做展示,这种模式称为model2。
servlet就是原有控制器的一种实现方式,strus2当中的Action也是控制器的一种实现方式

2):控制器核心作用

接收用户的请求,调用业务功能,根据处理的结果控制程序的运行流程。
控制器里都需要实现的核心代码:接收用户请求,处理业务逻辑,控制程序流程运转。
1、接收client请求参数,
2、调用业务对象,
3、流程跳转。或者是页面跳转。
不论是原生Servlet,SpringMVC,还是Structs,这些MVC工具都是要做这些是几个事情,如果说我们的代码
超出了这个范畴的话,说明我们的代码写的位置不是很合理。

3):这些控制器时存在的问题


A:接收参数时的问题

1、代码冗余
2、只能接收字符串类型的数据,其他类型需要进行手工转换
3、无法自动封装对象。
以上这两行代码,大量内容都是重复的。读取文本文件,通过应用层协议,传递过来的数据传递过来的时候,
初步接收的时候都是字符串,但是后续开发过程中,我们需要吧id转换成long或者其他类型的值。
接收数据的过程中,不能封装程一个对象。例如一个User对象。以上的缺点都是后续
SpringMVC帮我们做的事。

B:调用业务对象过程中

还得new创建对象,这样造成了耦合

C:流程跳转或者页面跳转存在的问题

1、跳转路径耦合:我们采用的forward进行跳转。出现了路径耦合
2、宇视图层技术耦合。

二: SpringMVC学习要点


1:SpringMVC的三种开发模式


1):传统的试图开发

通过作用域(request,session)进行数据的传递
通过试图层技术进行数据的展示(jsp,freemaker,thymeaf)进行数据的展示
知识点和servlet区别不大。

2):前后端分离的开发

多种新的请求发送方式
restful的访问方式。
通过httpMessageconverter进行数据响应,不在通过jsp,free,或者thymleaf

3):Spring5 引入的webflux开发

替换了传统的JavaWeb开发,一种新的web开发方式
通过NettyServer进行web通信。


2:创建父子工程


1):什么叫父子工程

父子工程就是先创建一个父工程,再在父工程地下创建若干个子工程,父工程用于管理项目结构和依赖,
依赖全部在父工程当中进行设置。我们后续的boot和cloud都是采用父子工程的设置。
ctrl+shift+alt+s快速进入project structure选项中。我们先设置JDK为1.8,在设置语言级别为1.8,
然后就该创建父工程了。父子工程创建好之后如何在pom文件当中如何体现父子级关系呢?

常见好的目录结构如下:
在这里插入图片描述

父子工程创建好时候,父工程主要是控制项目结构依赖版本,具体业务代码的开发都是在子工程当中。当我们创建好之后,我们就会发现,并没有按照标准的maven目录给我们创建。我们的src/main/下边应该还有一个java源码目录和一个resource资源目录。当然还有我们的测试目录。我们手动进行修复。


2):web.xml

web.xml文件基于maven骨架创建的版本他的servlet版本是2_3,我们使用Tomcat8版本,需要我们的Servlet支持3.x以上的版本,Tomcat9需要支持4.x以上的版本。我们删除掉这个配置文件,使用idea帮我们进行创建新的,基本步骤是:
在这里插入图片描述


3):对某个子工程进行部署

我们是父子工程,我们将子工程当中的依赖,构建都去掉,因为父工程都为我们做好了。
搭建好web项目之后,我们需要对他进行部署,也可能是对其中的某一个web工程进行部署,我们如何来部署一个web项目呢?打开add configuration这时候来到我们Tomcat的设置目录,点击local,选择TomcatServer
在这里插入图片描述
在这里插入图片描述
然后再deployment当中选择部署应用,我们选择的不要选择war包的形式,要选择普通目录(带exploded)的方式,方便我们后续进行调试。ApplicationContext是对我们web应用的名字进行设置我们选择basic。回到Server当中,我们对VM opetions做一些设置,也就是虚拟机参数:
-Dfile.encoding=UTF-8这个参数是防止Tomcat启动的时候控制台打印出现乱码。端口我们习惯上改为8989。基于此我们已经能够看出来,当前项目中父工程下一共有4个子工程,我们使用idea整合tomcat,并将其中的要给子项目部署到Tomcat服务器当中。我们已经搭建好了web项目的环境(web父子工程),接下来我们需要搭建一下SpringMVC环境的搭建。


三:SpringMVC环境的搭建


1:引入依赖jar包

整体来讲SpringMVC是相对于Spring来讲,我们就多了一个MVC的包,值得注意的是,我们需要在父工程当中引入所有的依赖。

<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.2version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.18version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.48version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.6version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.1.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>5.1.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjrtartifactId>
<version>1.8.8version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.3version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.25version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
<version>1.7.25version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>org.logback-extensionsgroupId>
<artifactId>logback-ext-springartifactId>
<version>0.1.4version>
dependency>
<dependency>
<groupId>org.yamlgroupId>
<artifactId>snakeyamlartifactId>
<version>1.25version>
dependency>
dependencies>

补充说明&#xff1a;
如何设置maven依赖添加之后&#xff0c;自动导入&#xff1a;
右边maven有一个小扳手&#xff0c;选择Auto-reload settings进来之后&#xff0c;选择any changes即可
另外&#xff0c;我们所有的依赖都只在我们的父工程当中进行了配置&#xff0c;但是我们子工程当中的maven依赖是都能依赖到&#xff0c;都能看得到的&#xff0c;可见父工程的依赖完全可以供子工程进行使用。


2&#xff1a;导入框架配置文件

作为SpringMVC来讲&#xff0c;他的配置文件就是原有Spring的配置文件&#xff0c;SpringMVC既然衍生自Spring很多的功能都是公用的。

两个注意事项&#xff1a;
1&#xff1a;SpringMVC的配置文件明后名称可以随意命名&#xff0c;但是我们在这里叫做&#xff1a;dispatcher.xml
2&#xff1a;SpringMVC的配置文件放置路径可以随意放置&#xff0c;但是这次我们放到根下&#xff0c;准确来讲是资源文件夹的根下。有了这两个特殊的说明之后。我们就可以在SpringMVC项目中引入他的配置文件了。
资源文件夹的根目录下就是resources底下&#xff0c;这个dispatcher.xml文件本质上就是Spring的配置文件。


3&#xff1a;初始化配置

对配置文件进行相应的配置


1)&#xff1a;web.xml


xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation&#61;"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version&#61;"4.0">



dispatcherServlet

org.springframework.web.servlet.DispatcherServlet




contextConfigLocation




classpath:dispatcher.xml





1


dispatcherServlet
/



2)&#xff1a;dispatcher.xml


xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context&#61;"http://www.springframework.org/schema/context"
xmlns:mvc&#61;"http://www.springframework.org/schema/mvc"
xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">








4&#xff1a;初始化配置当中细节


1)&#xff1a;dispatcher起到了什么作用

DispacherServlet我们习惯称之为前端控制器或者叫中央控制器。他的核心作用有两点&#xff1a;

1&#xff1a;创建Spring的工厂和容器。
我们每次测试的时候都需要创建Spring的工厂&#xff0c;在工厂当中去获取我们的对象。
然而在Web开发当中&#xff0c;我们Spring工厂对象是交由我们的前端控制器来创建的&#xff0c;所以这个在我们配置以后就等效于我们已经在Tomcat服务启动的时候就已经创建了Spring的工厂&#xff0c;所以这块就等效于我们进行了new ClassPathXmlApplicationContext(“dispacher.xml”)&#xff1b;所以这里边需要配置文件的名称和路径&#xff0c;这也是为什么我们需要将Spring配置文件的信息写入Web.xml当中。
因为DispathcherServlet封装的Spring工厂的创建只能通过读取XML文件的形式&#xff0c;所以无法迁移到纯注解的开发上。但是目前的SpringMVC是无法做到纯注解开发的&#xff0c;直到我们后边有了更高级的课程才能迁移到纯注解编程上去。

2&#xff1a;控制SpringMVC的内部运行流程。
内部运行流程是怎么流转的&#xff0c;这些相关的操作&#xff0c;必须等我们深入学习SpringMVC源码之后&#xff0c;才能会有更深入的了解。这里边只需要注意的是&#xff0c;他控制了SpringMVC的运行流程。


2)&#xff1a;SpringMVC的配置文件dispatcher.xml

mvc:annotation-driven/作用&#xff1a;
这块配置的主要作用就是&#xff1a;引入了SpringMVC的核心功能&#xff0c;主要引入了2个核心类型&#xff1a;RequestMappingHandlerMapping
RequestMappingHandlerAdapter
配置文件当中引入这个标签就是在SpringMVC项目中引入了这两个关键类。这两个类起到的作用
RequestMappingHandlerMapping&#xff1a;实现了HandlerMapper接口&#xff0c;并将其诸注册到请求注册表当中。
RequestMappingHandlerAdapter&#xff1a;实现了HandlerAdaper接口&#xff0c;主要作用就是处理请求适配器&#xff0c;他是专门处理请求的适配器&#xff0c;确定调用某个符合要求的控制器类中的具体服务的方法。
所以在这&#xff0c;整个SpringMVC控制器的调用&#xff0c;都是交由这个Adapter来完成的&#xff0c;他会在N多个控制器当中找到那个符合要求的控制器&#xff0c;并且调用这个控制器当中的某个方法&#xff0c;对外提供服务。

我们来验证我们以上的想法&#xff1a;
首先我们将左边的任务栏调整为浮动模式&#xff1a;项目上右键—> view mode&#xff1a;floot修改为浮动模式&#xff0c;找到我们项目中依赖管理的地方&#xff0c;在找到我们webmvc的jar包
打开下图这个文件之后&#xff0c;下面可以看到一组key_value这样的配置&#xff0c;前端的key是&#xff1a;http://www.springframework.org/schema/mvc这个含义就是说这一组标签都是所有核心配置文件当中mvc开头的标签都是由这个Schema来对应
后续的Value是一个类&#xff0c;这个类专门用来处理这些个对标签的类&#xff0c;我们说一切皆对象&#xff0c;这些对象就是我们用来处理这些标签的对象。
在这里插入图片描述

package org.springframework.web.servlet.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MvcNamespaceHandler extends NamespaceHandlerSupport {
public MvcNamespaceHandler() {
}
public void init() {
this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
this.registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
this.registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
this.registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
this.registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
this.registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
this.registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
this.registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
this.registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
this.registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
this.registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
this.registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
this.registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
}
}

打开这个类之后&#xff0c;我们看到了annotation-driven对应了一个新的类型。也就这样这个标签更具体的处理类是后边对应的这个。我们在进入到这个类之后&#xff0c;确实引入了我们上述的两个类型&#xff1a;

package org.springframework.web.servlet.config;
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
public static final String HANDLER_MAPPING_BEAN_NAME &#61; RequestMappingHandlerMapping.class.getName();
public static final String HANDLER_ADAPTER_BEAN_NAME &#61; RequestMappingHandlerAdapter.class.getName();
}

至此就证明了咱们上述表述的正确性。


这个标签就不陌生了&#xff0c;他就是为了注解扫描。这里边需要注意的是什么&#xff1a;因为DispathcherServlet封装的Spring工厂的创建只能通过读取XML文件的形式&#xff0c;所以无法迁移到纯注解的开发上。这样就导致了&#xff0c;我们这里边开发方式是&#xff1a;Spring配置文件&#43;基础注解的形式。

基础注解: &#64;Component,&#64;Service,&#64;Repository,&#64;Controller,&#64;Scope,&#64;Transactional等
高级注解: &#64;Confiquration,&#64;Bean,&#64;ComponentScan等
后续SpringMVC高级版的课程&#xff0c;会使用纯注解版开发&#xff0c;与SpringBoot的使用方式高度一致。







推荐阅读
  • 本文探讨了一种统一的语义数据模型,旨在支持物联网、建筑及企业环境下的数据转换。该模型强调简洁性和可扩展性,以促进不同行业间的插件化和互操作性。对于智能硬件开发者而言,这一模型提供了重要的参考价值。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 服务器虚拟化存储设计,完美规划储存与资源,部署高性能虚拟化桌面
    规划部署虚拟桌面环境前,必须先估算目前所使用实体桌面环境的工作负载与IOPS性能,并慎选储存设备。唯有谨慎估算贴近实际的IOPS性能,才能 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 本文探讨了在一个物理隔离的环境中构建数据交换平台所面临的挑战,包括但不限于数据加密、传输监控及确保文件交换的安全性和可靠性。同时,作者结合自身项目经验,分享了项目规划、实施过程中的关键决策及其背后的思考。 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • 本文探讨了服务器系统架构的性能评估方法,包括性能评估的目的、步骤以及如何选择合适的度量标准。文章还介绍了几种常用的基准测试程序及其应用,并详细说明了Web服务器性能评估的关键指标与测试方法。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • PHP函数的工作原理与性能分析
    在编程语言中,函数是最基本的组成单元。本文将探讨PHP函数的特点、调用机制以及性能表现,并通过实际测试给出优化建议。 ... [详细]
author-avatar
英英2502927137
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有