spring mvc 使用

spring mvc 是基于 Servlet API 构建的 Web 框架,围绕一个 DispatcherServlet 设计的,这个 Servlet 将请求分发给各个处理器,支持可配置的处理器映射、视图渲染、地区、时区和主题解析,以及对文件上传。默认处理程序基 于@Controller@RequestMapping 注释,Spring为处理器方法提供了极其多样灵活的配置。Spring 3.0以后提供了@Controller注解机制、@PathVariable注解以及一些其他的特性,你可以使用它们来进行RESTful web站点和应用的开发。

一、spring mvc 的处理流程

spring mvc 流程图

spring mvc 流程图

流程说明

  1. 用户发送请求至 前端控制器DispatcherServlet
  2. DispatcherServlet 收到请求后调用 处理器映射HandlerMapping
  3. HandlerMapping 根据请求的 url 找到具体的处理器,生成处理器对象Handler 及处理器拦截器HandlerIntercepter(如果有则生成)一并返回给前端控制器DispatcherServlet
  4. DispatcherServlet 通过处理器适配器 HandlerAdapter 调用具体的处理器Controller
  5. 处理器 Controller 执行完后返回模型和视图 ModelAnView
  6. DispatcherServlet 将 ModelAnView 传给视图解析器 ViewResolver,ViewResolver 解析后返回具体的视图 View
  7. 前端控制器 DispatcherServlet对视图View进行渲染视图(将模型数据填充至视图中)并响应用户

二、DispatcherServlet

DispatcherServlet 要使用 Java 配置或在 web.xml 根据 Servlet 规范进行声明和映射。然后 DispatcherServlet 使用 Spring 配置来发现它需要的用于请求映射、视图解析、异常处理等的组件。

<web-app>
    <!-- 在启动Web容器时,自动装配spring的配置信息 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 需要加载的上下文配置文件路径 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:conf/spring/applicationContext*.xml</param-value>
    </context-param>

    <!-- DispatcherServlet -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:conf/spring/applicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在这里存在两个 contextConfigLocation,一个是给ContextLoadrListener,一个是给DispatcherServlet

都是用于加载上下文,一个是spring的,一个是springMVC的,其中ContextLoadrListener先加载,然后才是DispatcherServlet。

  • DispatcherServlet 一般会加载MVC相关的bean配置管理(如: ViewResolver, Controller, MultipartResolver, ExceptionHandler)
  • ContextLoaderListener一般会加载整个Spring容器相关的bean配置管理(如: Log, Service, Dao, PropertiesLoader)

也就是如果我把 @Controller 的注解声明放到 ContextLoadrListener 中的配置文件去加载是不可以的,DispatcherServlet 到时对这个 controller 会无感知。
DispatcherServlet 的上下文仅仅是 Spring MVC 的上下文, 而 ContextLoaderListener 的上下文则对整个Spring都有效. 也就是 DispatcherServlet 可以使用 spring 的上下文,但是 spring 不能使用 DispatcherServlet 的上下文,一般 Spring web 项目中同时会使用这两种上下文


url-pattern 路径匹配问题

路径匹配的优先级为

  1. 完全匹配(如:/test/test.do)
  2. 路径匹配 /* (如:/* 、/app/*)
  3. 扩展名匹配 *.(如:*.jsp 不能直接用 *
  4. 另外还有一个 /

//* 的区别
/* 是路径匹配,像是模糊匹配,会匹配到该路径下所有的 URL 请求,包括带扩展名的文件如 *.jsp、*.css、*.js 等等
/ 的优先级是低于扩展名匹配的,它只能匹配到如 /toIndex 这样的路径

三、使用注解的控制器

Spring MVC 提供基于注释的编程模型,使用 @Controller 和 @RestController 注解标记控制器来表达请求映射,请求输入,异常处理等。带注解的控制器具有灵活的方法签名,不必扩展基类,也不必实现特定的接口

1、声明

要使用 @Controller 和 @RestController 注解,你得要告诉 spring mvc 要扫描解析的位置,可以将组件扫描添加到 Java 配置中

@Configuration
@ComponentScan("com.example.web")
public class WebConfig {
    // ...
}

或者是在 spring mvc 的bean配置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:p="http://www.springframework.org/schema/p"
    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">

    <context:component-scan base-package="com.example.web"/>
    <!-- ... -->
</beans>

@RestController 是 @Controller 和 @ResponseBody 的组合,相当于在这个控制器的每个方法上都注解了 @ResponseBody

2、请求映射

1)@RequestMapping

使用 @RequestMapping 注解能将请求映射到控制器的方法。可以在类级别使用它来表示共享映射,或者在方法级别使用它来缩小到特定的端点映射

另外还有与 HTTP方法匹配的映射注解: @GetMapping,@PostMapping,@PutMapping,@DeleteMapping,和@PatchMapping。(@GetMapping 等效@RequestMapping(method=HttpMethod.GET))

虽然默认情况下,@RequestMapping 与所有HTTP方法匹配,但大多数控制器方法应该映射到特定的HTTP方法而不是使用@RequestMapping

@RestController
@RequestMapping("/persons")
class PersonController {

    @GetMapping("/{id}")
    public Person getPerson(@PathVariable Long id) {
        // ...
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void add(@RequestBody Person person) {
        // ...
    }
}

2)路径匹配

请求路径还能使用 通配符

  • ? 匹配一个字符
  • * 匹配路径段中的零个或多个字符
  • ** 匹配零个或多个路径段

另外,还可声明 URI变量并通过 @PathVariable 访问它们的值

@GetMapping("/owners/{owner}/pets/{petId}")
public Pet findPet(@PathVariable("owner") Long ownerId, @PathVariable Long petId) {
    // ...
}

其正则表达式的语法为{varName:regex}

3)处理控制器的方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值