Spring MVC API: 5.0.4.RELEASE 阅读笔记
控制器(Controller)的实现
控制器是应用程序逻辑的处理入口,主要负责去调用service层已经实现的服务。
工作流程:控制器接收到用户请求并进行解析,然后将其转化为一个模型model交给视图,由视图解析器渲染成页面返回给用户。
1.4. Annotated Controllers: @Controller @RestController
1.4.1. Declaration
Spring MVC提供了一个基于注释的编程模型,其中@Controller和@RestController组件使用注释来表示请求映射、请求输入、异常处理等。带注释的控制器具有灵活的方法识别标志,无需扩展基类或实现特定接口。
分派器(
DispatcherServlet
)会自动扫描所有注解了@Controller
的类,检测其中通过@RequestMapping
注解配置的方法。
1、自定义控制器的bean组件:
遵循WebApplicationContext的组件标准,而且spring支持自动检测在类路径下的@Component类与自动注册bean组件。
- 配置类:为了能够自动检测到控制器的bean组件,需要使用@ComponentScan:
@Configuration
@ComponentScan("org.example.web")
public class WebConfig
-
xml文件配置:
<context:component-scan base-package="org.example.web"/>
2、@RestController
是@Controller和@ResponseBody的结合体,一方面表明这是一个控制器,另一方面其方法继承了@ResponseBody,因此该类中方法直接写入响应体,而不是通过视图解析和HTML模板呈现
3、面向切面(AOP)代理
@Controller控制器默认选择AOP代理,可使用@Transactional管理事务,但是在控制器需要实现特定接口【而该接口又不支持Spring Context的回调(比如InitializingBean
, *Aware
等接口)】的时候,则需要自行配置代理。
For example with
<tx:annotation-driven/>,
change to <tx:annotation-driven proxy-target-class="true"/>
1.4.2. Request Mapping
@RequestMapping
注解默认会映射所有的HTTP请求方法。如果仅想接收某种请求方法,请在注解中指定之@RequestMapping(method=GET)
以缩小范围。把控制器中的一系列处理方法当成是一系列独立的服务节点,每个从类级别和方法级别的
@RequestMapping
注解中获取到足够请求路径映射信息。【RequestMappingHandlerMapping】
There are also HTTP method specific shortcut variants of @RequestMapping
:
@GetMapping
eg.该方法接受一个模型model并以字符串Sring形式返回一个视图名@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
在类级别使用@RequestMapping来表示共享映射, 再在控制器方法上使用可区别的映射方式。即classes level +method level的映射组成了一个特定的http请求路径。
- 一般来说,类级别的注解负责将一个特定(或符合某种模式)的请求路径映射到一个控制器上,同时通过方法级别的注解来细化映射,即根据特定的HTTP请求方法(“GET”“POST”方法等)、HTTP请求中是否携带特定参数等条件,将请求映射到匹配的方法上。
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
URI patterns:URI模板
URI模板是一个类似于URI的字符串,只不过其中包含了一个或多个的变量名。当你使用实际的值去填充这些变量名的时候,模板就退化成了一个URI。即URI进行了参数化。
您可以使用glob模式和通配符映射请求:
- ? 匹配一个字符
- *匹配路径段中的零个或多个字符
- **匹配零个或多个路径段
1、@PathVariable:可以声明URI变量并使用**@PathVariable**访问它们的值:
在Spring MVC中你可以在方法参数上使用
@PathVariable
注解,将其与URI模板中的参数绑定起来:URI变量将自动转换为适当的类型,或者引发“TypeMismatchException”。默认情况下支持简单类型 - int、long、Date,您可以注册对任何其他数据类型的支持。请参见类型转换和绑定方法。
Spring MVC可通过显式命名@PathVariables中变量名来找到URI模板中相对应的变量。
URI变量可以显式地命名为 - ,例如@PathVariable(“customId”)
如果URI模板中的变量名与方法的参数名是相同的,则你可以不必再指定一次。
一个方法可以拥有任意数量的
@PathVariable
注解
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {
//如果URI模板中的变量名与方法的参数名是相同的,则可以不必再指定一次。
@GetMapping("/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
}
@RequestMapping(path="/owners/{ownerId}}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
// 具体的方法代码…
}
2、可以使用正则表达式声明uri变量:
语法:
{varName:regex}
第一部分定义了变量名,第二部分就是你所要应用的正则表达式Spring MVC使用PathMatcher契约和来自Spring core的AntPathMatcher实现进行URI路径匹配。
下面的方法提取名称、版本和文件扩展名:
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) {
// ...
}
3、Pattern comparison:模式比较/路径匹配
最佳匹配:This done via AntPathMatcher.getPatternComparator(String path)
which looks for patterns that more specific.
匹配顺序:
-
即越具体 匹配分数越高,URI模板变量的数目和通配符数量的总和最少的那个路径模板更准确。
-
匹配得分:URI变量>单个通配符>多个通配符>前缀模式>/**
默认的映射模式 /** 不包括在评分中,并且总是最后排序。此外,前缀模式(如 /public/** )被认为比其他任何不包括双通配符的模式更不具体。
更多的细节请参考这两个类:
AntPatternComparator
和AntPathMatcher
。值得一提的是,PathMatcher类是可以配置的。