springMVC

Spring与Web环境集成

ApplicationContext获取方式

应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。

在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。

WebApplicationContextUtils

上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。

所以我们需要做的只有两件事:

  1. 在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)

  2. 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

导入Spring集成web的坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

配置ContextLoaderListener

<!--全局参数-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的监听器-->
<listener>
    <listener-class>
       org.springframework.web.context.ContextLoaderListener
   </listener-class>
 </listener>

获取应用上下文对象

ApplicationContext applicationContext =    
    WebApplicationContextUtils.getWebApplicationContext(servletContext);
    Object obj = applicationContext.getBean("id");

知识要点

Spring集成web环境步骤

  1. 配置ContextLoaderListener监听器

  2. 使用WebApplicationContextUtils获得应用上下文

SpringMVC基本概念

三层架构和MVC

三层架构

我们的开发架构一般都是基于两种形式,一种是C/S架构,也就是客户端/服务器,另一种是B/S架构,也就是浏览器服务器.

在JavaEE开发中,几乎全都是基于B/S架构的开发.那么在B/S架构中,系统标准的三层架构包括:表现层. 业务层. 持久层.

三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的.

三层架构中,每一层各司其职,接下来我们就说说每层都负责哪些方面:

表现层:也就是我们常说的web层.它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web层,web需要接收http请求,完成http响应.
       表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示.
       表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端.
       表现层的设计一般都使用MVC模型.(MVC是表现层的设计模型,和其他层没有关系)

业务层:也就是我们常说的service层.它负责业务逻辑处理,和我们开发项目的需求息息相关.
       web层依赖业务层,但是业务层不依赖web层. 业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性.(也就是我们说的,事务应该放到业务层来控制)

持久层:也就是我们是常说的dao层.负责数据持久化.包括数据层(数据库)和数据访问层.
      数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中.
      通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的.

MVC模型

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计创建 Web 应用程序表现层的模式.

MVC中每个部分各司其职:

Model(模型):通常指的就是我们的数据模型.作用一般情况下用于封装数据.

View(视图): 通常指的就是我们的jsp或者html.作用一般就是展示数据的. 通常视图是依据模型数据创建的.

Controller(控制器): 是应用程序中处理用户交互的部分.作用一般就是处理程序逻辑的.它相对于前两个不是很好理解
    这里举个例子,例如:
        我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等. 这时候表单输入要求年龄必须是1~100之间的整数.姓名和性别不能为空.并且把数据填充到模型之中. 此时除了js的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做的. 当校验失败后,由控制器负责把错误页面展示给使用者. 如果校验成功,也是控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求.

SpringMVC概述

SpringMVC是什么

SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于 Spring FrameWork 的后续产品,已经融合在Spring Web Flow里面.

Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等.

SpringMVC已经成为目前最主流的 MVC 框架之一,并且随着Spring3.0的发布,全面超越 Struts2,成为最优秀的 MVC 框架. 它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口.同时它还支持RESTful编程风格的请求.

SpringMVC在三层架构的位置

SpringMVC的优势

1. 清晰的角色划分:前端控制器(DispatcherServlet). 请求到处理器映射(HandlerMapping). 处理器适配器(HandlerAdapter). 视图解析器(ViewResolver). 处理器或页面控制器(Controller). 验证器( Validator). 命令对象(Command 请求参数绑定到的对象就叫命令对象). 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象).

2. 分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要.

3. 由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象.

4. 和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的.

5. 可适配,通过 HandlerAdapter 可以支持任意的类作为处理器.

6. 可定制性,`HandlerMapping`, `ViewResolver` 等能够非常简单的定制.

7. 功能强大的数据验证. 格式化. 绑定机制.

8. 利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试.

9. 本地化主题的解析的支持,使我们更容易进行国际化和主题的切换.

10. 强大的 JSP 标签库,使 JSP 编写更容易.

还有比如RESTful风格的支持. 简单的文件上传. 约定大于配置的契约式编程支持. 基于注解的零配置支持等等.

SpringMVC入门程序

发送一个请求给后台程序,后台能够接收到该请求并且执行对应的业务方法,输出一段话。并且返回一个成功的页面。

SpringMVC开发环境搭建

创建项目

创建Maven的WEB项目,补全目录解构

添加依赖

添加SpringMCV开发的依赖jar包

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <!--spring版本锁定-->
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-api</artifactId>
      <version>9.0.10</version>
        <scope>provided</scope>
    </dependency>
  </dependencies>

SpringMVC入门程序

配置核心控制器

web.xml中配置SpringMVC的核心控制器

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

  <!--配置SpringMVC核心控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>

    <!-- 配置servlet启动时加载对象,不配是使用时加载,这里一般是启动初始化 -->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!--配置springmvc过请求过滤器,/表示所有请求都经过springmvc处理-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

创建SpringMCV配置文件

创建SpringMCV配置文件springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置创建spring容器要扫描的包 -->
    <context:component-scan base-package="com.itheima"></context:component-scan>

</beans>

创建index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello SpringMVC!</h2>

<!--编写超链接,点击超链接访问springmvc_01项目下的hello资源-->
<a href="/springmvc_01/hello">
    访问HelloServlet
</a>

</body>
</html>

编写控制器并配置

编写控制器并使用注解配置HelloController

@Controller("helloController")
public class HelloController {

    //设置sysHello方法的请求路径为"hello"
    @RequestMapping(path = "/hello")
    public String sysHello(){
        System.out.println("第一个SpringMVC程序");
        return "success";
    }
}

配置视图解析器

修改SpringMCV配置文件springmvc.xml配置视图解析器(掌握)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置创建spring容器要扫描的包 -->
    <context:component-scan base-package="com.itheima"></context:component-scan>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

</beans>

访问测试

打开浏览器,输入 : http://localhost:8080/springmvc_01/index.jsp

SpringMVC流程图示

快速入门程序总结

SpringMVC的开发步骤 :

  1. 导入SpringMVC相关坐标
  2. 配置SpringMVC核心控制器DispathcerServlet
  3. 创建Controller类和视图页面
  4. 使用注解配置Controller类中业务方法的映射地址
  5. 配置SpringMVC核心文件 spring-mvc.xml
  6. 客户端发起请求测试

SpringMVC的组件解析

SpringMVC的执行流程

①用户发送请求至前端控制器DispatcherServlet。
②DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
④DispatcherServlet调用HandlerAdapter处理器适配器。
⑤HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
⑥Controller执行完成返回ModelAndView。
⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ViewReslover解析后返回具体View。
⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

SpringMVC组件解析

  1. 前端控制器:DispatcherServlet

    用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由

它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

  1. 处理器映射器:HandlerMapping

    HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的

映射方式,例如:配置文件方式,实现接口方式,注解方式等。

  1. 处理器适配器:HandlerAdapter

    通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理

器进行执行。

  1. 处理器:Handler

    它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由

Handler 对具体的用户请求进行处理。

  1. 视图解析器:View Resolver

    View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

  2. 视图:View

    SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

SpringMVC注解解析

入门程序中, 我们在控制方法上添加了RequestMapping注解 , 那么这个注解在案例中起到什么样的作用呢 ?

作用 :

  • RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

位置 :

  • RequestMapping注解可以作用在方法和类上 , 作用在类上, 要访问类中的方法就必须添加类上的访问路径 , 一般用于模块化开发

属性 :

  • path 指定请求路径的url
  • value 同path属性 , 指定请求路径的url
  • mthod 指定该方法的请求方式
  • params 指定限制请求参数的条件
  • headers 发送的请求中必须包含的请求头
/**
 * 此控制器的访问路径为 /user
 */
@RequestMapping("/user")
@Controller
public class UserController {

    /**
     *此方法的访问路径为   /add  使用value属性指定
     */
    @RequestMapping(value = "/add")
    public  void add(){
        System.out.println("添加用户....");
    }

    /**
     *此方法的访问路径为   /add  使用path属性指定 同value
     * 此方法的请求方式为 get
     */
    @RequestMapping(path = "/update",method = RequestMethod.GET)
    public  void update(){
        System.out.println("更新用户....");
    }

    /**
     *此方法的访问路径为   /findAll  ,必须包含Accept请求头
     *
     */
    @RequestMapping(path = "/findAll",headers = {"Accept"})
    public  void findAll(){
        System.out.println("查询所有用户....");
    }

    /**
     * 请求路径为/findById
     * 请求方式为GET
     * 必须包含id参数
     */
    @RequestMapping(path = "/findById",method = RequestMethod.GET,params = {"id"})
    public  void findById(){
        System.out.println("查询所有用户....");
    }
}

SpringMVC的XML配置

SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀

视图解析器

我们可以通过属性注入的方式修改视图的的前后缀

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

推荐阅读更多精彩内容