SpringMVC小结

发布时间 2024-01-10 08:44:18作者: 菜鸡前来

1、SpringMVC是啥?

MVC是Model-View-Control

顾名思义,它是 Spring 框架中处理模型(Model)- 视图(View)- 控制器(Controller)或 MVC 模式的一个模块。它结合了 MVC 模式的所有优点和 Spring 的便利性。

2、为什么要用SpringMVC

如果没有MVC设计模式。程序间的各层之间依赖非常强,耦合度高..严重违背了高内聚低耦合的设计原则。而WebMVC将控制逻辑和功能处理,模型和视图进行了分离。

降低耦合但是WebMVC也有严重的缺点:

  • 控制器(controller) 1.控制逻辑较为复杂,而且每个模块都需要一个控制器,(可能每一个页面都需要一个控制器) 2.请求参数到模型的封装麻烦。 3.视图的选择严重依赖于Servlet API ,这样很能甚至不可能更换视图 4.给视图传入模型数据 也依赖于Servlet API.如果要更换视图那么技术也要改变。 模型(model) 使用JavaBean组件,(域模型层+业务层+持久层)导致JavaBean组件类庞大。不利于开发人员管理 视图(view) 被绑定于Jsp,很难更换视图

如何解决WebMVC的缺点:

从服务到工作者模式:服务到工作者:Front Controller + Application Controller + Page Controller + Context即,前端控制器+应用控制器+页面控制器(也有称其为动作)+上下文

优点:

  • 实现了用户视图代码和业务逻辑代码的解耦合:也就是说,当业务逻辑发生变化时,只需要修改业务逻辑相关的代码就可以了,不需要改动视图类代码。同样地,当需要改变用户视图的时候,只需要修改视图代码就可以了,不需要修改业务逻辑相关的代码。如此一来,项目代码的开发和维护工作量大大降低了

3、SpringMVC执行流程

(1)当用户通过浏览器发起一个HTTP请求,请求直接到前端控制器DispatcherServlet (2)前端控制器接收到请求以后调用处理器映射器HandlerMapping,处理器映射器根据请求的URL找到具体的Handler,并将它返回给前端控制器; (3)前端控制器调用处理器适配器HandlerAdapter去适配调用Handler; (4)处理器适配器会根据Handler去调用真正的处理器去处理请求,并且处理对应的业务逻辑; (5)当处理器处理完业务之后,会返回一个ModelAndView对象给处理器适配器,HandlerAdapter再将该对象返回给前端控制器;这里的Model是返回的数据对象,View是逻辑上的View。 (6)前端控制器DispatcherServlet将返回的ModelAndView对象传给视图解析器ViewResolver进行解析,解析完成之后就会返回一个具体的视图View给前端控制器。(ViewResolver根据逻辑的View查找具体的View) (7)前端控制器DispatcherServlet将具体的视图进行渲染,渲染完成之后响应给用户(浏览器显示)。

个人理解:用户发起请求的时候会访问前端控制器(DispatcherServlet),根据用户发的请求去找映射器(HandlerMapping),然后把映射器返回给前端控制器(DispatcherServlet),并去适配这个映射器,然后用具体的Conroller执行,然后返回给返回给前端映射器,返回给用户。

4、 Spring MVC框架简介

  • Spring MVC框架是基于MVC模式,使用Java语言开发实现的一个轻量级Web框架

  • Spring MVC就是一套万能工具,它包含了实现MVC模式三大角色的组件,还有协调角色组件间工作的其他组件。但是使用Spring MVC框架却非常简单,通过一套注解,就可以让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还能够实现 RESTful 编程风格的API接口

  • 它是Spring家族中的一员,和Spring容器是同一个妈妈生的。正因为这一点,通过简单的配置,就能够让Spring MVC框架和Spring容器一起使用。也就是说在基于Spring容器开发的Java Web项目中添加Spring MVC框架,就像给笔记本电脑加装一块固态硬盘。

  • 不同于以前框架只提供接口,然后让使用者自己根据接口写实现类来实现功能,Spring MVC提供了一整套完善的组件,可以直接使用。这就相当于以前的框架只给你提供设计图纸,你需要根据设计图纸自己把工具造出来,而现在Spring MVC直接给你一套现成的工具箱,里面有你用得到的各种工具。而且使用Spring MVC框架提供这些工具也巨简单,通过一些简单的注解就搞定了,不需要编写繁琐冗长的代码,简直比夏天喝雪碧还要爽

  • SpringMVC是以强大的SPring容器为基础的框架。

5、Spring MVC注解详解

5.1、组件型注解

  • @Controller:实现MVC模式中的控制器角色

    1. 在Java类上添加这个注解后,就相当于告诉Spring MVC框架说:”这个Java类要当做控制器来使用,这个Java类当做MVC模式的控制器了,并且将这个控制器放入Spring容器中,交由Spring容器来托管。

  • @RequestMapping:

    1. 它通常是和@Controller一起搭配使用的。,要说Controller是放在类上面的,那么RequestMapping一般就是放在方法名上面.(也可以放在类名上)

例子1:

@Controller
public class MyController {
    //注解的value参数中写上"/api/v1"这么简单那如果用户又发出了一个调用uri为api/v2的请求呢?很简单,在MyController类中再写一个v2方法,然后用
    @RequestMapping(value = "/api/v1")
    public String v1(){
       return "v1";
     }
}

例子2:

@Controller
@RequestMapping("/api")
public class MyController {
   @RequestMapping("/v1")
   public String v1(){
       return "v1";
   }
​
@RequestMapping("/v2")
   public String v2(){
       return "v2";
   }
}
  • value参数:@RequestMapping注解还有其他的常用参数。

  • method:定义http请求的方式,包括GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE,如果请求方式和定义的方式不一样则请求无法成功。如:@RequestMapping(value = "/v1", method = RequestMethod.POST),说明只接收用POST方式发送过来的http请求。如果我们不写这个method 参数,则默认接受GET和POST两种类型的请求。

  • headers:定义http请求中必须包含某些指定的请求头,如:@RequestMapping(value = "/v1", headers = "content-type=text/*"),说明请求中必须要包含"text/html", "text/plain"这种Content-type内容的请求头,才是一个匹配的请求。

  • params:定义http请求中必须包含的参数值。如:@RequestMapping(value = "/v1", params= “username”),说明请求中必须包含有username参数。

  • 总结:如果说用户的http请求是一封邮件,那么上面这些@RequestMapping注解的参数就规定了我们映射的uri可以接收哪些符合条件的邮件。例如method参数要求只接收普通邮件(GET请求)、电报邮件(POST请求)还是几种都可以接收。headers参数要求接收哪种类型的邮件,比如普通的文本邮件,还是莫尔斯电码邮件。params参数要求邮件中必须包含有对应的内容等等

5.2、Spring MVC的请求型注解

  • 例如在http://localhost:8080/myapp/api/v1 这个url地址中,

    1. localhost是”域名或者ip地址“,代表我们的web应用部署在网络上的哪台服务器上;

    2. 8080是端口号,是服务器进行网络通信而开放的一个出入口;

    3. myapp是web应用名称,

    4. api/v1是处理用户http请求的具体的模块路径,简称uri。

  • 总结:通俗的来讲就是:嗨服务器,通过8080端口,让位于localhost这台服务器上的名字叫myapp的应用web应用,调用他的uri为api/v1的处理模块来处理我的http请求--------前面的三个部分,也就是http://localhost:8080/myapp这一块,一般是不变的。后面的api/v1这个uri是可变的,也就是我们要让Spring MVC框架去映射的东西。

5.3、Spring MVC的参数型注解

  • @RequestParam:绑定User实体类接收form表单的参数

    1. 通过@RequestParam注解,form表单中的username和passwd参数就塞进了@RequestParam注解后面,String对象中的同名参数里。

      package com.lyh.controller;
      ​
      import com.lyh.pojo.User;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      ​
      @Controller
      @RequestMapping("/api")
      public class MyController {
          @RequestMapping("/v1")
          public String v1(@RequestParam String username, @RequestParam String passwd) {
      ​
              // 将获取到的参数放入实体类中
              User user = new User();
              user.setUsername(username);
              user.setPasswd(passwd);
      ​
              // 业务处理代码
      ​
              return "v1";
          }
      }
  • @RequestBody:主要用来接收前端传递给后端的;Spring MVC框架就会取出存放在request body中的json字符串,并自动地转换成User实体类

    1. 除了表单参数以外,现在还流行将参数放入request body中进行传递的方式,这也是目前Restful接口都在使用的方式,很多前端框架也大都采用这种传参方式。下面咱就一块看一下怎样使用@RequestBody注解来接收http请求中封装在request body中的请求参数。

    2. @RequestBody注解主要用来接收前端传递给后端的,用JSON字符串表示的数据的。现在很多前端框架或者前端的小伙伴,都喜欢把请求参数转换成JSON字符串后,放入http请求的request body中,然后发送给后端。在收到这样的请求后,就可以用@RequestBody注解,来取出request body中的json字符串,并且自动地将其转换成指定的实体类。所以,@RequestBody注解很适合用在前后端分离开发模式中。那我们该怎么使用@RequestBody注解来接收前端小伙伴传递过来的json字符串呢?下面老师就用一段代码来说明一下,聪明的你肯定一看就懂。

      // 使用@RequestBody注解接收request body中的参数
      @Controller
      @RequestMapping("/api")
      public class MyController {
      @RequestMapping("/v1")
      public String v1(@RequestBody User user){
      ​
          // 业务处理代码
      ​
          return "v1";
      }
      }
  • @PathVariable:通过在uri路径中用{}将参数包起来,然后再用@PathVariable注解,将方法的方法参数跟路径中的同名参数绑定,就能够接收uri路径中的参数了。

    // 使用@PathVariable注解接收uri中的参数
    @Controller
    @RequestMapping("/api")
    public class MyController {
    ​
        @RequestMapping("/{id}/v1")
        public String v1(@PathVariable String id){
    ​
            // 业务处理代码
    ​
            return "v1";
        }
    }

6、实战:注解开发

  • 新建maven项目(记住是一个空的maven项目,让后在maven项目中添加web)

  • 配置tomcat

  • 在pom.xml文件中导入依赖

    <?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>com.lyh</groupId>
        <artifactId>SpringMVCStudy</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>Springmvc-01-serlect</module>
            <module>Spring-01-servlect</module>
            <module>Springmvc-02-hellomvc</module>
            <module>springmvc-03-annotation</module>
        </modules>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.8.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
        </dependencies>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
        </build>
    ​
        <properties>
            <maven.compiler.source>11</maven.compiler.source>
            <maven.compiler.target>11</maven.compiler.target>
        </properties>
    ​
    </project>
  • 在项目结构(Project Settings)中找到Artifacts找到你新创的项目在WEB-INF下添加lib包,在里面把依赖都加载进去

    image-20240109112922840

  • 编写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">
        <!--    配置DispatchServlet:这是SpringMVC的核心配置文件,请求分发器-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
            <!--        启动级别-->
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
  • 编写配置文件springmvc-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!--    自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
    ​
        <context:component-scan base-package="com.lyh.controller"></context:component-scan>
        <!--    过滤静态资源-->
        <mvc:default-servlet-handler></mvc:default-servlet-handler>
        <!--
           处理器映射器
            <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
            处理器适配器
            <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
        -->
        <!--    这句话相当于上面这两句,帮你自动引入-->
        <mvc:annotation-driven></mvc:annotation-driven>
        <!--    试图解析器-->
        <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--        前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <!--        后缀-->
            <property name="suffix" value=".jsp"></property>
        </bean>
    ​
    ​
    </beans>
  • 编写controller

    package com.lyh.controller;
    ​
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    ​
    @Controller
    public class HelloController {
        @RequestMapping("/hello")
        public String hello(Model model){
            model.addAttribute("msg","hellorcons");
    ​
            return "hello";
        }
    ​
    }
  • 编写页面测试

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    ${msg}
    </body>
    </html>

     

     

  •