关于后端:赶紧收藏Spring-MVC-万字长文笔记我愿奉你为王者笔记

3次阅读

共计 7492 个字符,预计需要花费 19 分钟才能阅读完成。

Spring MVC

Spring MVC 是目前支流的实现 MVC 设计模式的企业级开发框架,Spring 框架的一个子模块,无需整合 Spring,开发起来更加便捷。

什么是 MVC 设计模式?

将应用程序分为 Controller、Model、View 三层,Controller 接管客户端申请,调用 Model 生成业务数据,传递给 View。

Spring MVC 就是对这套流程的封装,屏蔽了很多底层代码,凋谢出接口,让开发者能够更加轻松、便捷地实现基于 MVC 设计模式的 Web 开发。

Spring MVC 的外围组件

  • DispatcherServlet:前置控制器,是整个流程管制的外围,管制其余组件的执行,进行对立调度,升高组件之间的耦合性,相当于总指挥;
  • Handler:处理器,实现具体的业务逻辑,相当于 Servlet;
  • HandlerMapping:DispatcherServlet 接管到申请之后,通过 HandlerMapping 将不同的申请映射到不同的 Handler;
  • HandlerInterceptor:处理器拦截器,是一个接口,如果须要实现一些拦挡解决,能够实现该接口;
  • HandlerExecutionChain:处理器执行链,包含两局部内容:Handler 和 HandlerInterceptor(零碎会有一个默认的 HandlerInterceptor,如果须要额定设置拦挡,能够增加拦截器);
  • HandlerAdapter:处理器适配器,Handler 执行业务办法之前,须要进行一系列的操作,包含表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等,这些操作都是由 HandlerAdapter 来实现,开发者只须要将注意力集中业务逻辑的解决上(适配器设计模式),DispatcherServlet 通过 HandlerAdapter 来执行不同的 Handler;
  • ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet;
  • ViewResolver:视图解析器,DispatcherServlet 通过它将逻辑视图解析为物理视图,最终将渲染后果响应给客户端。

Spring MVC 的工作流程

  • 客户端申请被 DispatcherServlet 接管;
  • 依据 HandlerMapping 映射到 Handler;
  • 生成 Handler 和 HandlerInterceptor;
  • Handler 和 HandlerInterceptor 以 HandlerExecutionChain 的模式一并返回给 DispatcherServlet;
  • DispatcherServlet 通过 HandlerAdapter 来调用 Handler 的办法来实现业务逻辑解决;
  • Handler 返回一个 ModelAndView 给 DispatcherServlet;
  • DispatcerServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器,将逻辑视图解析为物理视图 View;
  • ViewResolver 返回一个 View 给 DispatcherServlet;
  • DispatcherServlet 依据 View 进行视图渲染(将模型数据 Model 填充到视图 View 中);
  • DispatcherServlet 将渲染后的后果响应给客户端。

Spring MVC 流程非常复杂,理论开发中很简略,因为大部分的组件不须要开发者创立、治理,只须要通过配置文件的形式实现配置即可,真正须要开发者进行解决的只有 Handler、View。

如何应用?

  • 创立 Maven 工程,pom.xml;

(当 IDEA 工具左侧不显示项目名称,能够敞开 IDEA,删除.idea 文件夹,从新关上 IDEA)

(利用 webapp 模板创立的 Web 工程目录,src/main/webapp,java 源文件目录和 resources 资源目录须要本人创立)

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
</dependencies>
  • 在 web.xml 中配置 DispatcherServlet;
<?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">
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
  • springmvc.xml
<?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"
       xsi:schemaLocation="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">
    <!-- 配置主动扫描,将组件扫描到 IoC 容器中 -->
    <context:component-scan base-package="org.westos"></context:component-scan>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <!--value="/" 代表根目录 -->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • 创立 Handler
package org.westos.controller;

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

/**
 * @author lwj
 * @date 2020/12/13 22:29
 */
@Controller
public class HelloHandler {@RequestMapping("/index")
    public String index() {System.out.println("执行了 index...");
        return "index";
    }
}
  • 配置 Tomcat 服务器,启动,运行,胜利。

http://localhost:8080/index

Spring MVC 注解

  • @RequestMapping

Spring MVC 通过 @RequestMapping 注解将 URL 申请与业务办法进行映射,在 Handler 的类定义处和办法定义处都能够增加 @RequestMapping,在类定义处增加,相当于客户端多了一层拜访门路;

  • @Controller

@Controller 在类定义处增加,将该类交给 IoC 容器来治理(联合 springmvc.xml 的主动扫描配置应用),同时使其成为一个控制器,能够接管客户端申请;

package org.westos.controller;

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

/**
 * @author lwj
 * @date 2020/12/13 22:29
 */
@Controller
@RequestMapping("/hello")
public class HelloHandler {@RequestMapping("/index")
    public String index() {System.out.println("执行了 index...");
        return "index";
    }
}

http://localhost:8080/hello/index

  • @RequestMapping 相干参数

1、value:指定 URL 申请的理论地址,是 @RequestMapping 的默认值。

@RequestMapping("/index")
public String index() {System.out.println("执行了 index...");
    return "index";
}

等于

@RequestMapping(value = "/index")
public String index() {System.out.println("执行了 index...");
    return "index";
}

2、method:指定申请的 Method 类型,GET、POST、PUT、DELETE。

@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {System.out.println("执行了 index...");
    return "index";
}

上述代码示意 index 办法只能够接管 GET 申请。

应用 Postman 工具来模仿一个 POST 申请拜访 index 办法。

3、params:指定申请中必须蕴含某些参数,否则无奈调用该办法。

@RequestMapping(value = "/index", method = RequestMethod.GET, params = {"name", "id=5"})
public String index() {System.out.println("执行了 index...");
    return "index";
}

上述代码示意申请中必须蕴含 name 和 id 两个参数,并且 id 的值必须是 5。

http://localhost:8080/hello/index?name=zhangsan&id=5

对于参数绑定,在形参列表中通过增加 @RequestParam 注解实现 HTTP 申请参数与业务办法形参的映射。

(当申请参数名和办法形参名统一时,能够不必增加 @RequestParam 注解)

@RequestMapping(value = "/index", method = RequestMethod.GET, params = {"name", "id=5"})
public String index(@RequestParam("name") String str, @RequestParam("id") int age) {System.out.println("执行了 index...");
    System.out.println(str);
    System.out.println(age);
    return "index";
}

上述代码示意将申请的参数 name 和 id 别离赋给形参 str 和 age,同时主动实现了数据类型转换,将字符串 ”10″ 转换为 int 类型的 10,再赋给 age,这些工作都是由 HandlerAdapter 实现。

Spring MVC 同时反对 RESTful 格调的 URL。

传统类型:http://localhost:8080/hello/index?name=zhangsan&id=5

RESTful:http://localhost:8080/hello/rest/zhangsan/10

@RequestMapping(value = "/rest/{name}/{id}")
public String rest(@PathVariable("name") String name, @PathVariable("id") int id) {System.out.println(name);
    System.out.println(id);
    return "index";
}

通过 @PathVariable 注解实现申请参数与形参的映射。

  • 映射 Cookie

Spring MVC 通过映射能够间接在业务办法中获取 Cookie 的值。

@RequestMapping(value = "/cookie")
public String cookie(@CookieValue(value = "JSESSIONID") String sessionId) {System.out.println(sessionId);
    return "index";
}
  • 应用 JavaBean 绑定参数

Spring MVC 会依据申请参数名和 JavaBean 属性名进行主动匹配,主动为对象填充属性值,同时反对级联属性。

package org.westos.entity;

import lombok.Data;

/**
 * @author lwj
 * @date 2020/12/19 15:57
 */
@Data
public class Address {private String value;}
package org.westos.entity;

import lombok.Data;

/**
 * @author lwj
 * @date 2020/12/19 15:58
 */
@Data
public class User {
    private long id;
    private String name;
    private Address address;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%-- 页面上的门路与重定向是须要增加 Web 我的项目的上下文门路的 --%>
    <form action="/hello/register" method="post">
        <label for="id"> 用户 id:</label>
        <input type="text" name="id" id="id"> <br>
        <label for="name"> 用户名:</label>
        <input type="text" name="name" id="name"> <br>
        <label for="value"> 用户地址:</label>
        <input type="text" name="address.value" id="value"> <br>
        <input type="submit" value="注册">
    </form>
</body>
</html>
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String register(User user) {System.out.println(user);
    return "index";
}

上述会呈现中文乱码问题,只需在 web.xml 中增加 Spring MVC 自带的过滤器即可。

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

JSP 页面的转发与重定向

Spring MVC 默认是以转发的模式响应 jsp 页面。

  1. 转发
@RequestMapping("/forward")
public String forward() {
    return "forward:/index.jsp";
    //return "index";
}
  1. 重定向
@RequestMapping("/redirect")
public String redirect() {return "redirect:/index.jsp";}

总结

另外我这里为大家筹备了一线大厂面试材料和我原创的超硬核 PDF 技术文档,以及我为大家精心筹备的多套大厂面试题(不断更新中),欢送关注公众号:前程有光 支付!心愿大家都能找到心仪的工作!

正文完
 0