SpringMVC

In my solitude of heart I feel the sigh of this widowed evening veiled with mist and rain.

这寡独的黄昏,幕着雾与雨,我在我的心的孤寂里,感觉到它的叹息。 

SpringMVC官方文档

Spring MVC

Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

Spring MVC 是结构最清晰的 Servlet+JSP+JavaBean 的实现

在 Spring MVC 框架中,Controller 替换 Servlet 来担负控制器的职责,用于接收请求,调用相应的 Model 进行处理,处理器完成业务处理后返回处理结果。Controller 调用相应的 View 并对处理结果进行视图渲染,最终客户端得到响应信息。

Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。

在Spring Web MVC中,你可以使用任何对象来作为命令对象或表单返回对象,而无须实现一个框架相关的接口或基类。

使用SpringMVC基础配置

点击跳转springmvc

原生配置实现SpringMVC

SpringMVC执行原理

DispatcherServlet其实就是个Servlet(它继承自HttpServlet基类),同样也需要在你web应用的web.xml配置文件下声明。你需要在web.xml文件中把你希望DispatcherServlet处理的请求映射到对应的URL上去。

1
2
3
4
5
6
7
8
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.bobo.servlet.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现

  1. DispatcherServlet表示前置控制器,使整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求;

  2. HandlerMapping为处理器映射,DispatcherServlet调用HandlerMapping,HandlerMapping根据请求查找Handler;

    1
    2
    <!--Handler 处理器-->
    <bean id="/hello" class="com.bobo.Controller.HelloController"/>
  3. HandlerExecution表示具体的Handler,其主要作用是根据请求查找控制器,比如 SpringMVC站点的hello控制器

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等;

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler;

  6. Handler让具体的Controller执行;

  7. controller将具体执行的信息返回给HandlerAdapter,如ModelAndView;

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet;

  9. DispatcherServlet调用试图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!--视图解析器:DispatcherServlet给他的ModelAndView
    1。获取了ModelAndView中的数据
    2。解析ModelAndView中的视图名
    3。拼接视图名字,找到对应视图
    4。将数据渲染到视图上
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
    </bean>
  10. 视图解析器将解析的逻辑视图名传递给DispatcherServlet;

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图;

  12. 最终视图呈现给用户。

注解开发SpringMVC

首先,进行SpringMVC基础配置+注解配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.bobo.controller"/>

<!-- 让Spring MVC不处理静态资源 .css .js .html .mp3 .mp4 -->
<mvc:default-servlet-handler/>

<!-- 支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。 -->
<mvc:annotation-driven/>

pring 2.5以后引入了基于注解的编程模型,你可以在你的控制器实现上添加@RequestMapping@RequestParam@ModelAttribute等注解。

点击跳转注解,查看SpringMVC相关注解

实例

HelloController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.bobo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {

@RequestMapping("/h1")
public String hello(Model model) {
//封装数据
model.addAttribute("msg", "Hello,SpringMVCAnnotation");

//会被视图解析器处理
return "hello";
}
}

hello.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%--
Created by IntelliJ IDEA.
User: pro
Date: 2021/10/14
Time: 23:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>

控制器Controller

  1. 控制器负责提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现;
  2. 控制器负责解析用户的请求并将其转换为一个模型;
  3. 在Spring MVC中一个控制器类可以包含多个方法;
  4. 在SpringMVC中,对Controller的配置方法有很多种。

Spring MVC 视图重定向

控制器通常都会返回一个逻辑视图名,然后视图解析器会把它解析到一个具体的视图技术上去渲染。

重定向前缀——redirect:

redirect:。如果返回的视图名中含有redirect:前缀,那么UrlBasedViewResolver(及它的所有子类)就会接受到这个信号,意识到这里需要发生重定向。然后视图名剩下的部分会被解析成重定向URL。

这种方式与通过控制器返回一个重定向视图RedirectView所达到的效果是一样的,不过这样一来控制器就可以只专注于处理并返回逻辑视图名了。

重定向前缀——forward:

对于最终会被UrlBasedViewResolver或其子类解析的视图名,你可以使用一个特殊的前缀:forward:。这会导致一个InternalResourceView视图对象的创建(它最终会调用RequestDispatcher.forward()方法),后者会认为视图名剩下的部分是一个URL

RestFul风格

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

特性

  1. 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。

  2. 状态转换(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。

    HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转换”(State Transfer)。

    而这种转换是建立在表现层之上的,所以就是“表现层状态转换”。

    具体说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。他们分别对应四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。

    传统方式操作资源

    http://127.0.0.1/item/queryUser.action?id=1 查询,GET
    http://127.0.0.1/item/saveUser.action 新增,POST
    http://127.0.0.1/item/updateUser.action 更新,POST
    http://127.0.0.1/item/deleteUser.action?id=1 删除,GET或POST

    使用RESTful操作资源

    http://127.0.0.1/item/1 查询,GET

    http://127.0.0.1/item 新增,POST

    http://127.0.0.1/item 更新,POST

    http://127.0.0.1/item/1 删除,GET或POST

SpringMVC对RESTful的支持

点击跳转SpringMVC对RESTful的支持
  1. 使路径变得更加简洁
  2. 获得参数更加方便,框架会自动进行类型转换
  3. 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求
  4. 安全

API设计风格基本规则

  1. 使用名词而不是动词

  2. Get方法和查询参数不应该涉及状态改变

    使用PUT, POSTDELETE 方法 而不是 GET 方法来改变状态,不要使用GET 进行状态改变:

  3. 使用复数名词

    不要混淆名词单数和复数,为了保持简单,只对所有资源使用复数。

  4. 使用子资源表达关系

    如果一个资源与另外一个资源有关系,使用子资源

  5. 使用Http头声明序列化格式

    在客户端和服务端,双方都要知道通讯的格式,格式在HTTP-Header中指定

  6. 为集合提供过滤 排序 选择和分页等功能

  7. 使用Http状态码处理错误

查看评论