SpringMVC原理、源码分析

默认的DispatcherServlet配置

在spring-webmvc-4.3.16.RELEASE.jar/org/springframework/web/servlet/路径下的DispatcherServlet.properties是默认的DispatcherServlet配置,包括视图解析器、映射处理器等,打比方,如果配置了InternalResourceViewResolver,则将会覆盖默认的ViewResolver实现列表。

 1 # Default implementation classes for DispatcherServlet's strategy interfaces.
 2 # Used as fallback when no matching beans are found in the DispatcherServlet context.
 3 # Not meant to be customized by application developers.
 4 
 5 org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
 6 
 7 org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
 8 
 9 org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
10     org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
11 
12 org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
13     org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
14     org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
15 
16 org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
17     org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
18     org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
19 
20 org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
21 
22 org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
23 
24 org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

 DispatcherServlet处理流程

当配置好DispatcherServlet并有请求过来,DispatcherServlet将会进行如下流程:

1、WebApplicationContext在请求中被搜索并绑定,作为控制器和流程中的其他元素可以使用的属性。它默认通过DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE进行绑定。
2、本地解析器被绑定到请求,以便在处理请求时(呈现视图、准备数据等)处理场所中的元素。
3、主题解析器被绑定到请求,让视图等元素决定使用哪个主题。
4、如果您指定了一个多部件文件解析器,那么该请求将被检查为多部分;如果发现了多部件,则请求包裹在多parthttpservletrequest中,以便在过程中进行其他元素的进一步处理。
5、将会寻找一个合适的handler。如果一个handler被发现的话,和这个handler(预处理器、后期处理器以及控制器)相关的执行链将会被执行,用于准备一个model或者渲染。
6、如果返回一个模型,就会呈现一个视图。如果没有返回模型,(可能是由于预处理器或后处理器拦截请求,可能出于安全原因),没有视图,因为请求已经完成了。

HelloWorldController:
package com.led.controller;

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

/**
 * @author Alan
 * @date 2018/5/23 22:07
 * @Controller:表明这个是一个控制器
 * @RequestMapping:定义请求路径
 */
@Controller
public class HelloWorldController {
    @RequestMapping("/helloWorld")
    public String helloWorld(Model model){
        model.addAttribute("message","Hello world");
        return "helloworld";
    }
}

该类接收了一个Model并返回了一个String类型的view.

@RequestMapping的组合形式

Spirng4.3版本建议使用以下组合注解的形式来简化常用的HTTP方法并更好的表达注释的含义。

@GetMapping==>@RequestMapping(method = RequestMethod.GET)
@PostMapping==>@RequestMapping(method = RequestMethod.POST)
@PutMapping==>@RequestMapping(method = RequestMethod.POST)
@DeleteMapping==>@RequestMapping(method = RequestMethod.DELETE)
@PatchMapping==>@RequestMapping(method = RequestMethod.PATCH)

 @Controller and AOP Proxying

在某些情况下,控制器可能需要在运行时用AOP代理来装饰。一个例子是,如果您选择直接在控制器上有@transactional注释。在这种情况下,对于控制器来说,我们建议使用基于类的代理这通常是控制器的默认选择。然而,如果一个控制器必须实现一个不是Spring上下文回调的接口(例如初始化bean、感知等等),那么您可能需要显式地配置基于阶级的代理。例如,将<tx:annotation-driven/>改为<tx:annotation-driven proxy-target-class="true"/>。

URI Template Patterns

例如,URI模板http://www.example.com/users/{userId}包含变量userId。实例如http://www.example.com/users/fred。

在Spring MVC中通过在方法参数上使用@PathVariable注解,将请求里面的变量绑定到形参上。

@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable String ownerId, Model model) {
    Owner owner = ownerService.findOwner(ownerId);
    model.addAttribute("owner", owner);
    return "displayOwner";
}

下面这种更具体:

@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
    // implementation omitted
}

一个方法里面可以有多个@PathVariable注解

@GetMapping("/owners/{ownerId}/pets/{petId}")
public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
    Owner owner = ownerService.findOwner(ownerId);
    Pet pet = owner.getPet(petId);
    model.addAttribute("pet", pet);
    return "displayPet";
}

@PathVariable的参数可以是int、long、Date、String等。

后缀匹配

".*"的后缀形式可以匹配/person.*,比如/person.pdf/person.xml。

使用@RequestParam注解为方法参数绑定请求参数

@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm {

    // ...

    @GetMapping
    public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
        Pet pet = this.clinic.loadPet(petId);
        model.addAttribute("pet", pet);
        return "petForm";
    }

    // ...

}

如果请求参数不是必须的,可以写成:@RequestParam(name="id", required=false)

猜你喜欢

转载自www.cnblogs.com/stm32stm32/p/9079627.html