SpringMVC 入门

SpringMVC框架概述

Spring Web MVC是基于Servlet API构建的传统Web框架,并且从一开始就已包含在Spring框架中

与Spring Web MVC并行,Spring Framework 5.0引入了一个新的反应式Web框架,其名称“ Spring WebFlux;

理解:

首先SpringMVC 是一个MVC构架模式的web框架,是基于Servlet的,从Spring第一个版本就一起推出了,

传统web框架,指的是SpringMVC依然使用多线程同步并发的方式来处理请求,现如今大家都在鼓吹异步并发多么多么好,从测试数据来看异步并发效率的确更好,但是其并不成熟,极大多数公司项目还没有更新到异步技术,盲目的进行重构可能会引发更多的问题, 并且异步编程在代码结构上会产生较大的变化,对于初学者而言,掌握难度是较大的;

构架图:


Spring-MVC在系统中的位置

思考:

若没有SpringMVC框架,我们该如何去编写一个较大的web项目呢,可以发现在选课系统中出现了大量的Servlet,因为一个请求地址就需要一个Servlet,使得项目体积变大,且Servlet是长期存在内存的;

第一步,我们希望用一个Servlet来处理多个请求甚至是所有请求,就需要实现能根据请求路径查找处理请求方法的逻辑,这也是SpringMVC要做的第一件事情;

DispatcherServlet:前端控制器

用户请求首先到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的调度中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。

Handler:处理器

Handler是继DispatcherServlet前端控制器的后端控制器,DispatcherServlet会将请求发送至对应的Handler来进行处理。Handler是处理业务逻辑的地方,需要我们自己来编写具体代码,等同于之前的Service层

HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求路径找到Handler,springmvc提供了不同的映射器实现不同的映射方式,例如:BeanName映射,配置文件映射,注解映射等。

HandlAdapter:处理器适配器

通过HandlerAdapter来执行Handler,因为Handler有不同形式,意味着调用方式是不同的,这是适配器模式的应用,我们也可以扩展适配器来实现新的Handler;

ViewResolver:视图解析器

ViewResolver负责从Handler中获取数据和视图,根据逻辑视名称查找物理视图文件,并查找View对象,再生成View对象;

View:视图

View的职责就是装配数据,SpringMVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。常用视图就是jsp。我们需要根据业务需求,通过页面标签或页面模版技术将模型数据展示给用户

当然还有一些其他的

请求处理流程简述

入门程序

pom依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>

  <artifactId>MVC01</artifactId>

  <version>1.0-SNAPSHOT</version>

  <packaging>war</packaging>

  <name>MVC01 Maven Webapp</name>

  <!-- FIXME change it to the project's website -->

  <url>http://www.example.com</url>

  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <maven.compiler.source>1.7</maven.compiler.source>

    <maven.compiler.target>1.7</maven.compiler.target>

  </properties>

  <dependencies>

    <!--  SpringMVC -->

    <dependency>

      <groupId>org.springframework</groupId>

      <artifactId>spring-webmvc</artifactId>

      <version>5.2.2.RELEASE</version>

    </dependency>

    <!--JEE相关的-->

    <dependency>

      <groupId>javax.servlet</groupId>

      <artifactId>jstl</artifactId>

      <version>1.2</version>

    </dependency>

    <dependency>

      <groupId>javax.servlet.jsp</groupId>

      <artifactId>javax.servlet.jsp-api</artifactId>

      <version>2.3.3</version>

      <scope>provided</scope>

    </dependency>

    <dependency>

      <groupId>javax.servlet</groupId>

      <artifactId>javax.servlet-api</artifactId>

      <version>4.0.1</version>

      <scope>provided</scope>

    </dependency>

  </dependencies>

</project>

web .exml配置

与在web项目中使用Spring中相同的是,我们也需要让SpringMVC随着web项目启动,SpringMVC的做法是利用DIspatcherServlet;

DispatcherServlet做了两个事情,1:初始化一个Spring容器,2:注册一个Servlet

SpringMVC本质上也是一个Spring容器,在不涉及WEB时使用方法和Spring没有任何区别;ß

url-pattern

只有请求地址能够匹配到到被DispatcherServlet的url-pattern的请求才会被SpringMVC处理,那么那些请求要交给SpringMVC处理呢,通常是除静态资源以外的请求;

常用pattern:

需要说明的是action并不是固定的不同公司可能不同,但无论是点什么,其目的都是为了和静态资源加以区分

创建控制器类

import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public classTestControllerimplementsController{

    @Override    publicModelAndViewhandleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)throwsException{

        ModelAndView modelAndView = new ModelAndView();//创建一个表示模型和视图的对象        modelAndView.setViewName("index.jsp");//设置视图名称        modelAndView.addObject("msg","hello springMVC");//添加视图需要的数据        //httpServletRequest.setAttribute("msg","hello SpringMVC"); //等同于上面一行        return modelAndView; //返回模型和视图给dispatcherServlet    }

}

ModelAndView,其实就是把视图资源和数据打包到一起,然后视图名称交给视图解析器,Object放到请求中;

注册控制器到容器中

springmvc.xml

<?xml version="1.0"encoding="UTF-8"?>

DispatcherServlet是按照请求路径来查找Handler,我们必须告诉SpringMVC,这个控制器是用来处理哪个请求地址的,默认情况下,SpringMVC会查找beanName与请求地址相同的Handler来处理;

测试:

打开浏览器输入地址:http://localhost:8080/MVC01_war_exploded/testController

我们在Request中添加了key为msg的字符内容hello SpringMVC

看到上述内容说明SpringMVC以及成功处理了请求;

注解配置Controller

上述方法每个Controller只能处理一个请求地址,不够灵活,且需要Controller实现指定接口,这是就需要使用注解来配置Controller了;

@Controller

该注解写在类上,用于注册控制器bean到容器中,这是之前以及学习过的

@RequestMapping("url")

该注解写在方法上时,用于为方法指定要匹配的url,该url是相对根路径的

写在类上时类上的url是相对于根路径,而类中方法则相对于类的url

案列:

@Controller//@RequestMapping("/user")publicclassUserController{@RequestMapping("/getMsg")publicModelAndViewgetMsg(){        ModelAndView modelAndView =newModelAndView();        modelAndView.setViewName("/index.jsp");        modelAndView.addObject("msg","hello SpringMVC annotation!");returnmodelAndView;    }}

请求地址:http://localhost:8080/MVC01_war_exploded/getMsg,可正常访问

当把类上注释的url打开时,上面的地址404了

正确地址:http://localhost:8080/MVC01_war_exploded/user/getMsg

需要注意的是:

viewName路径若不带/时则从当前请求的位置查找文件,带/则表示从根路径查找

默认配置阅览

我们完成了一个简单的入门案例,但是你会发现除了DispatcherServlet之外没有出现其他上面提到过的组件,那么它们是不是没有作用呢?

其实SpringMVC提供了很多默认配置,使我们可以快速的开项目,而无需繁琐的配置,在SpringMVC的包下可以找到一个DispatcherServlet.properties配置,这便是默认的配置文件了;

RouterFunctionMapping和HandlerFunctionAdapter都是webFlux中的这里不多关注;

SimpleServletHandlerAdapter默认是没有的,当需要使用Servlet相关API时使用,需要在配置文件中声明

注意:当手动添加了适配器后,系统就不会自动添加任何其他适配器了;

SimpleServletHandlerAdapter案例:

@Controller("/servletController")publicclassYouControllerextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest req, HttpServletResponse resp)throwsServletException, IOException{        resp.getWriter().println("servlet API");    }}

请求地址:http://localhost:8080/MVC01_war_exploded/servletController,记得注册Adapter到容器中;

在上述4中handler中最常用的是使用注解形式的;

视图解析配置

视图解析器用于查找视图文件,及生成视图对象,我们不用过多关注,唯一会用到的就是,为视图名称配置前缀和后缀从而简化,Handler中的书写

在一个实际项目中页面文件可能比较多,可以用文件夹管理,但是这导致我们在编写视图名称时更加繁琐,例如:

handler中:

这时就可在配置中对视图解析器进行相关设置;

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  <!--指定视图类型-->

    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

  <!--指定前缀-->

    <property name="prefix" value="/pages/jsp/"/>

  <!--指定后缀-->

    <property name="suffix" value=".jsp"/>

</bean>

处理器中:

@RequestMapping("/getMsg")publicModelAndViewgetMsg(){    ModelAndView modelAndView =newModelAndView();    modelAndView.setViewName("index");    modelAndView.addObject("msg","hello SpringMVC annotation!");returnmodelAndView;}

视图解析器会自动在viewName前后分别拼接前缀和后缀;如:/pages/jsp/index.jsp

启用MVC 配置

上面提到,SpringMVC默认会加载DispatcherServlet.properties中的配置作为默认配置,当我们需要添加额外的自定义配置时该怎么办呢?这是我们需要启用MVC配置,通过在配置文件中添加以下标签

<mvc:annotation-driven/>

为了减少配置项,该标签向容器中添加了提供MVC基础服务的Bean,并添加了json,xml,的转换器

有兴趣可以源码位置:web包下的AnnotationDrivenBeanDefinitionParser,

此时看不出该标签对系统有什么影响,但在后续自定义验证器,转换器时就不得不使用到该标签了

官方原话:

"in XML configuration, you can use the `<mvc:annotation-driven/>` element to enable MVC configuration, the preceding example registers a number of Spring MVC infrastructure beans and adapts to dependencies available on the classpath (for example, payload converters for JSON, XML, and others)"

作  者:CoderJerry

出  处:https://www.cnblogs.com/yangyuanhu/p/12271415.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,681评论 6 517
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,205评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 169,421评论 0 362
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,114评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,116评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,713评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,170评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,116评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,651评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,714评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,865评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,527评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,211评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,699评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,814评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,299评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,870评论 2 361

推荐阅读更多精彩内容