diff --git a/spring/Spring core/SpringMVC.md b/spring/Spring core/SpringMVC.md index 48f24e0..18fc08f 100644 --- a/spring/Spring core/SpringMVC.md +++ b/spring/Spring core/SpringMVC.md @@ -91,3 +91,95 @@ redirect:https://myhost.com/some/arbitrary/path #### 转发 以“forward:”前缀开头的view name会被转发。 +## Controller +### AOP代理 +在某些时候,可能需要AOP代理来装饰Controller,对于Controller AOP,推荐使用基于class的aop。 +例如想要为@Controller注解的类添加@Transactional注解,此时需要手动指定@Transactional注解的proxyTargetClass=true来启用基于class的动态代理。 +> 当为@Transactional注解指定了proxyTargetClass=true之后,其不光会将@Transactional的代理变为基于cglib的,还会将整个context中所有的autoproxy bean代理方式都变为基于cglib类代理的 +### Request Mapping +可以通过@RequestMapping来指定请求对应的url、http请求种类、请求参数、header和media type。 +还可以使用如下注解来映射特定的http method: +- @GetMapping +- @PostMapping +- @DeleteMapping +- @PutMapping +- @PatchMapping +相对于上述的注解,@RequestMapping映射所有的http method。 +#### URI Pattern +Spring MVC支持如下URI Pattern: +- /resources/ima?e.png : ?匹配一个字符 +- /resources/*.png : *匹配0个或多个字符,但是位于同一个path segment内 +- /resource/** : **可以匹配多个path segment(但是\*\*只能用于末尾) +- /projects/{project}/versions : 匹配一个path segment,并且将该path segment捕获到一个变量中,变量可以通过@PathVariable访问 +- /projects/{project:[a-z]+}/versions : 匹配一个path segment,并且该path segment需要满足指定的regex + +{varName:regex}可以将符合regex的path segment捕获到varName变量中,例如: +```java +@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}") +public void handle(@PathVariable String name, @PathVariable String version, @PathVariable String ext) { + // ... +} +``` +#### Pattern Comparasion +如果多个pattern都匹配当前URI,那么最佳匹配将会被采用。 +多个pattern中,更加具体的pattern会被采用。URI的计分方式如下: +- 每个URI变量计1分 +- *符号计1分 +- **符号计两分 +- 如果分数相同,那么更长的pattern会被选择 +- 如果分数和pattern length都相同,那么拥有比wildchar更多的的URI变量的模式会被选择 + +分数越高,那么pattern将会是更佳的匹配 +#### 消费media-type +可以在@RequestMapping中指定请求中的Content-Type类型来缩小请求映射范围 +```java +@PostMapping(path = "/pets", consumes = "application/json") +public void addPet(@RequestBody Pet pet) { + // ... +} +``` +consumes属性还支持“非”的操作,如下所示: +```java +// 其映射除text/plain之外的content-type +@PostMapping(path = "/pets", consumes = "!text/plain") +``` +#### 产生media-type +可以在@RequestMapping中指定produces属性来根据http请求header中的Accept属性来缩小映射范围 +```java +// 该方法会映射Accept属性为application/json的http请求 +@GetMapping(path = "/pets/{petId}", produces = "application/json") +@ResponseBody +public Pet getPet(@PathVariable String petId) { + // ... +} +``` +#### Parameters & Headers +可以通过请求参数或header来缩小@RequestMapping的映射。 +支持过滤条件为某参数是否存在、某参数值是否为预期值,header中某值是否存在、header中某值是否等于预期值。 +```java +// 参数是否存在 : myParam +// 参数是否不存在 : !myParam +// 参数是否为预期值 : myParam=myValue +@GetMapping(path = "/pets/{petId}", params = "myParam=myValue") +public void findPet(@PathVariable String petId) { + // ... +} + +// headers校验同样类似于params +@GetMapping(path = "/pets", headers = "myHeader=myValue") +public void findPet(@PathVariable String petId) { + // ... +} +``` +### handler method +#### 类型转换 +当handler方法的参数为非String类型时,需要进行类型转换。在此种场景下,类型转换是自动执行的。默认情况下,简单类型(int,long,Date,others)是被支持的。 +可以通过WebDataBinder来进行自定义类型转换。 +在执行类型转换时,空字符串""在转换为其他类型时可能被转化为null(如转化为long,int,Date).如果允许null被注入给参数,**需要将参数注解的required属性指定为false,或者为参数指定@Nullable属性。** +#### Matrix Variable +在Matrix Variable中,允许在uri中指定key-value对。path segment中允许包含key-value对,其中变量之间通过分号分隔,值如果存在多个,多个值之间通过逗号分隔。 +```shell +/cars;color=red,green;year=2012 +``` + +