认识SpringMVC,并用两种简单的方式实现MVC操作。

927 阅读6分钟

什么是 "MVC"?

  • MVC 就是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计的规范。

  • 是将业务逻辑、数据、显示分离的方法来组织代码

  • MVC主要作用是降低视图和业务逻辑的双向耦合

  • 它不是一种设计模式,而是一种架构模式(当然,不同的MVC存在差异)。

    Model(模型):数据模型,提供要展示的数据,因此包含数据和行为。可以认为是领域模型或JavaBean的组件(包含数据和行为),不过现在一般都分离来:Value Object(数据Dao)和服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。 View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想要看到的东西。 Controller(控制器):接收用户请求,委托给模型进行处理(状态的改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度圆的工作 以上划掉部分,了解即可

为什么要学习SpringMVC SpringMVC的优点很多: 轻量级、简单易学、能进行简单的junit测试、支持Restful风格、与Spring兼容性好,无缝结合.....当然最主要的是用的人多比较多。

除了SpringMVC还有哪些其他的服务器框架 常见的服务器端MVC框架有:Struts、SpringMVC、ASP.NET MVC、Zend Framework、JSF;常见的前端MVC框架有:Vue、Angularjs、React、Backbone;由MVC还演化出另一种设计模式如:MVP、MVVM 等等.....

MVC框架要做哪些事情

  1. 将url映射到Java类或Java类的方法。
  2. 封装用户提交的数据。
  3. 处理请求----调用相关的业务处理----封装响应数据。
  4. 将响应数据的数据进行渲染.jsp / html 等表示层数据。

中心控制器

Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始,使用Java 5或以上版本的用户可以采用基于注解的Controller声明方式。

SpringMVC框架像许多其他的MVC框架一样,以请求为驱动围绕一个中心的Servlet分派请求以及提供其他功能,DispatcherServlet是一个实际的Servlet(它继承自HttpServlet 基类)这里可以看到Dispatcher Servlet也是一个Servlet

用原始的方法实现一个MVC操作

首先需要写一个Dispatcher Servlet在web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--写一个DispatcherServlet,它是SpringMVC的核心:也叫请求分发器或者前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--绑定Spring(MVC)的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:xxxxx</param-value>
        </init-param>
        <!--设置启动级别为1-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--这里需要注意的是"<url-pattern>/</url-pattern>"处不要写成 /* ,
    如果写成 /* 的话会匹配所有的请求和所有的jsp文件,会出现嵌套循环的问题
    而 / 则不会 / 只会匹配所有的请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

从代码中可以看到需要绑定一个Spring(MVC)的配置文件,那么我们在resource目录下写一个配置文件给他绑定即可 Spring配置文件

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

    <!--配置映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <!--配置适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
        
    </bean>
    <bean id="/hello" class="com.molu.controller.HelloController"/>

</beans>

在spring配置文件中我们需要写一个映射器一个适配器和一个视图解析器(在实际的开发中并不需要把映射器和适配器显式的写出来)

之后我们需要编写一个能够让适配器找到的Controller类 在这里插入图片描述

创建好Controller类后需要让这个类继承Controller接口,实现了这个接口的类会获得控制器的功能(控制器用来处理请求和返回ModelAndView) 在这里插入图片描述

这里需要注意的是不要继承Controller的注解(也就是第二个)

实现了Controller接口后需要重写他的方法,重写该方法只需要返回一个ModelAndView即可 在这里插入图片描述 实现这个接口并重写他的方法后我们在这个方法里写我们自己的具体业务代码和视图跳转在这里插入图片描述 这里的视图跳转中传的test是我之前写好的jsp 在这里插入图片描述 视图跳转写完后我们的Controller类到这里就结束了,返回的ModelAndView会把视图的名字交给视图解析器去拼接

  <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>

拼接、数据填充完成后会把数据交给Dispatcher Servlet,由Dispatcher Servlet把数据给用户。 在这里插入图片描述 到这里原始的MVC实现方法就结束了,这种方法有一个缺陷,一个控制器中只能写一个方法。如果我们的网站有几十上百个接口 难道要写几十上百个类吗?而用注解来实现则不会有这方面的困惑。

注解实现MVC操作

注解实现MVC非常的方便 在真实开发中百分之九十都会使用注解的方式来进行操作,很少会使用上面这种原始的方法。

1. 首先为了避免Maven静态资源过滤的问题,我们在pom.xml中加上如下代码。

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

2. 接着我们写一个DispatcherServlet在web.xml中(同上一种方法)

    <!--这是一段死代码只需要修改servlet-name即可-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!--绑定spring(MVC)配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
        <!--设置启动级别-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- servlet-name与上面的对应,url处填写/即可(填写/*会匹配jsp文件导致出现循环嵌套的问题)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

3.绑定Spring(MVC)配置文件

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

    <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
    <context:component-scan base-package="com.molu.controller"/>

    <!--让SpringMVC不处理静态资源-->
    <mvn:default-servlet-handler/>

    <!--支持MVC注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入
    -->
    <mvn:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

4.最后编写我们的Controller类,在类中使用对应的注解

package com.molu.controller;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller //这里使用@Controller注解,让Spring能够扫描到这个类
public class HelloController {

    @RequestMapping("hello") //url地址
    public String hello(Model model){
        // 使用Model来封装数据 (这里的Model就是ModelAndView的简化版本,一般Model会用的比较多)
        model.addAttribute("msg","Hello,Molu");
        return "hello"; //返回的值会被视图解析器处理
    }
}

@Controller注解用于声明Spring类的实例,用@Controller声明的类就是一个控制器,且会被Spring托管。这个注解中的类的所有方法,如果返回值是String并且有具体的页面可以跳转,那么就会被视图解析器解析

@RequestMapping 的value值也就是请求的url地址,一般写在方法上面, 如果在类上使用这个注解,在url地址上就会多一层父关系,这个父关系的url(也就是类上的@RequestMapping的value值)需要写在方法上的RequestMapping的url前面

========================================================================

4.1在类上使用RequestMapping注解

下图代码就是在类上使用了RequestMapping注解,那么如果想访问hello方法中的Model封装的数据,就必须在url地址上加上一个"Hello"(也就是类上的@RequestMapping的value值 -eg:localhost:8080/Hello/hello 在这里插入图片描述 上图仅做示范,在本次的注解操作中并没有在类上使用Request Mapping注解

======================================================================= 5.之后我们在浏览器上输入 "localhost:8080/hello"进行测试,如图可以访问到我们用Model封装起来数据。

在这里插入图片描述

可以看到使用注解的开发十分便捷,大致步骤如下:

  1. 新建一个web项目
  2. 导入相关jar包依赖
  3. 编写web.xml,编写Dispatcher Servlet
  4. 编写Spring(MVC)配置文件
  5. 创建对应的控制类(Controller)
  6. 完善前端视图和controller之间的对应
  7. 测试运行调试

使用SpringMVC必须配置的三大件:

处理器映射器、处理器适配器、视图解析器

通常我们只需要手动配置视图解析器,而处理器映射器、处理器适配器我们只需要开启注解驱动即可,省去了大段的xml配置,提高开发效率。