本文以纯后端的角度,去研究Spring Controller在各种情况的行为,及各种属性的作用。

实验准备

利用https://start.spring.io/快速生成一个开箱即用的小巧spring boot项目,无需进行复杂配置,非常适合进行研究实验使用。

若以下例子未说明,结果为下述代码所示。

@Controller
@RequestMapping(value = "/terra")
public class TestController {
// 放置实验的Controller
}

端口号在application.properties设置为9000

server.port=9000
server.contextPath=/
server.tomcat.uri-encoding=UTF-8

@RequestMapping

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。(抄)

一. value

value不设置和设置为""的情况下会产生冲突,编译会报错。

    @RequestMapping()
public String voidController1() {
return "voidController1";
} @RequestMapping(value = "")
public String voidController2() {
return "voidController2";
}

两者可以看做等价,但是又存在区别。

value不设置的情况下,认为是默认控制器,此时不能令返回值=void,否则会在请求时报错

// TODO 需要翻源码了解为何报错

Circular view path [second]: would dispatch back to the current handler URL [/second] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

但是可以跳转到其他类下的路径,而value = "" 时则不会有这些问题.

@Controller
@RequestMapping(value = "/second")
public class SecondPageController { @RequestMapping()
public String defaultController() {
// 报错
// return "/terra";
return "/terra/test";
}
}

于是乎可以做到类似以下的杂技般有趣但又没多大意义的跳转,需要注意的是默认控制器无法直接使用本类下的子路径,原因不明。

@Controller
@RequestMapping(value = "/terra")
public class TestController { @RequestMapping(value = "test")
public String testController() {
System.out.println("测试请求");
return "/terra";
} @RequestMapping()
public String defaultController() {
System.out.println("请求跳转到了默认请求控制器");
// 无法跳转
// return "/jump";
return "/terra/jump";
} @RequestMapping(value = "jump")
public String jumpController() {
System.out.println("请求跳转到了jump");
return "void";
} @RequestMapping(value = "void")
public void voidController() {
System.out.println("请求跳转到了void,终止");
} }
localhost:9000/terra/test 或者localhost:9000/second 请求控制台输出:
测试请求
请求跳转到了默认请求控制器
请求跳转到了jump
请求跳转到了void,终止

顺带一提value支持中文,猜想支持的范围=String.equal,但是一般不会有猿们这么用吧

@Controller
@RequestMapping(value = "/中文")
public class ZnTestController { @RequestMapping(value = "测试")
public void testController() {
System.out.println("测试请求");
}
}

想写下一个内容的过程发现 value值中带不带“/”是等价的,下面两个test会报错,且用无斜杠与有斜杠的路径没有区别

@Controller
@RequestMapping("value")
public class ValueBindController { @RequestMapping(value = "/test")
public void hasSlash() {
System.out.println("有斜杠");
} @RequestMapping(value = "test")
public void noneSlash() {
System.out.println("无斜杠");
}
}

路径貌似不支持其他特殊字符,如#value或/#value时无法与localhost:/#value/test进行匹配

......好吧正题

value支持使用占位符对url进行值绑定到参数上,如下列形式,这种即是REST风格的入参形式

@Controller
@RequestMapping("value")
public class ValueBindController { @RequestMapping(value = "printValue/{value}")
public void printValue(@PathVariable String value) {
// localhost:9000/value/printValue/1
System.out.println(value);
} @RequestMapping(value = "printPrintValue/{value}")
public void printPrintValue(@PathVariable("value") String printValue) {
// localhost:9000/value/printPrintValue/1
System.out.println(printValue);
} @RequestMapping(value = "printValues/{value1}/{value2}")
public void printValues(@PathVariable String value1, @PathVariable Integer value2) {
// localhost:9000/value/printValues/1/2
System.out.println(value1 + "/" + value2);
} @RequestMapping(value = "printMap/{value1}/{value2}")
public void printValues(@PathVariable Map<String, String> map) {
// localhost:9000/value/printValues/1/2
System.out.println(map.get("value1") + "/" + map.get("value2"));
} @RequestMapping(value = "printList/{list}")
public void printValues(@PathVariable List<String> list) {
// localhost:9000/value/printList/1,2,3
list.stream().forEach(k -> System.out.print(k + " "));
System.out.println();
}
}

博客上有人提到过使用@PathVariable会产生截断问题,即value/{value},若输入为1.jpg,value =1。但是测试时发现非常非常的正常,版本问题么?

value支持多路径,如下,这种形式还可以解决当参数参数非必传时的问题

@Controller
@RequestMapping(value = "mul")
public class MulValueController { @RequestMapping(value = {"one", "two", "three"})
public void test() {
// localhost:9000/mul/one
// localhost:9000/mul/two
// localhost:9000/mul/three
System.out.println("多路径匹配");
} @RequestMapping(value = {"value/{value1}", "value/{value1}/{value2}"})
public void printValues(@PathVariable String value1, @PathVariable(required = false) String value2) {
// localhost:9000/value/1
// localhost:9000/value/1/2
System.out.println(value1 + "/" + value2);
}
}

value亦支持正则表达式

@Controller
@RequestMapping(value = "regex")
public class RegexController { @RequestMapping(value = "tel/{number:^18[0-9]\\d{8}$}")
public void telPhone(@PathVariable String number) {
// 匹配以18开头的手机号码
// localhost:9000/regex/tel/18123456890
System.out.println(number);
}
}

但是复杂一些的正则会出一些莫名其妙的错误,原因不明,比如

^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$

会报下面这个异常。

The number of capturing groups in the pattern segment (^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\d{8}$) does not match the number of URI template variables it defines, which can occur if capturing groups are used in a URI template regex. Use non-capturing groups instead.

二. method

method用于指定请求类型,如GET,POST

路径相同类型不同的方法可以共存(value =value , method != method) ,

如下GET请求会到getController,POST请求会执行postController,其余类型的请求会执行allController

    @RequestMapping(method = RequestMethod.GET)
public String getController() {
return "Get请求";
} @RequestMapping(method = RequestMethod.POST)
public String postController() {
return "Post请求";
} @RequestMapping()
public String allController() {
return "任意请求";
}

method支持多参数,这里用GET还是用POST都会调用这个方法

   @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
public String getPostController() {
return "GetOrPost请求";
}

待续

【Spring-Controller 整理研究】@RequestMapping略解的更多相关文章

  1. Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解

    一.控制器定义 控制器提供访问应用程序的行为,通常通过服务接口定义或注解定义两种方法实现. 控制器解析用户的请求并将其转换为一个模型.在Spring MVC中一个控制器可以包含多个Action(动作. ...

  2. Spring MVC 学习)——控制器与@RequestMapping详解

    Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解 一.控制器定义 控制器提供访问应用程序的行为,通常通过服务接口定义或注解定义两种方法实现. 控制器解析用户的请求 ...

  3. SpringMVC RequestMapping 详解

    SpringMVC RequestMapping 详解 RequestMapping这个注解在SpringMVC扮演着非常重要的角色,可以说是随处可见.它的知识点很简单.今天我们就一起学习Spring ...

  4. Spring Boot 之使用 Json 详解

    Spring Boot 之使用 Json 详解 简介 Spring Boot 支持的 Json 库 Spring Web 中的序列化.反序列化 指定类的 Json 序列化.反序列化 @JsonTest ...

  5. Spring boot注解(annotation)含义详解

    Spring boot注解(annotation)含义详解 @Service用于标注业务层组件@Controller用于标注控制层组件(如struts中的action)@Repository用于标注数 ...

  6. Spring学习 6- Spring MVC (Spring MVC原理及配置详解)

    百度的面试官问:Web容器,Servlet容器,SpringMVC容器的区别: 我还写了个文章,说明web容器与servlet容器的联系,参考:servlet单实例多线程模式 这个文章有web容器与s ...

  7. 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+SpringMVC项目详解

    http://blog.csdn.net/noaman_wgs/article/details/53893948 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+Spri ...

  8. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  9. springMVC(1)---@RequestMapping详解

    @RequestMapping详解 RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径.这句话,太熟悉了.   ...

随机推荐

  1. swust oj 984

    利用二叉树中序及先序遍历确定该二叉树的后序序列 1000(ms) 10000(kb) 2754 / 5599 已知二叉树的中序和先序遍历可以唯一确定后序遍历.已知中序和后序遍历可以唯一确定先序遍历,但 ...

  2. python全栈开发 * 继承性 层叠性 盒模型 标准文档流 * 180809

    ---恢复内容开始--- 一继承性 1.继承: 给父级设置一些属性,子级继承了父级的该属性,这就是我们的css中的继承. 2. 可继承: color . font-*(size). text-*(de ...

  3. SQL 序列-DML-DML-数据类型-用户管理、权限-事务-视图

    --DML--insert关键字--作用:往表中插入一条(多条)记录 --元祖(tuple)值式的插入(一次插入一条记录)--语法1:insert into tablename(column1,col ...

  4. Java第四次实践作业

    1 编写“电费管理类”及其测试类.  第一步 编写“电费管理”类 1)私有属性:上月电表读数.本月电表读数 2)构造方法:无参.2个参数 3)成员方法:getXXX()方法.setXXX()方法 4 ...

  5. [git] git怎样fork一个repo

    描述 我定制了一下strongswan的工程.然后想把我自己的定制变成一个repo push到远端git.tong.com与大家分享. 这个时候,应该怎么做? 如果你用过github的话.那么你可以理 ...

  6. python数据分析算法(决策树2)CART算法

    CART(Classification And Regression Tree),分类回归树,,决策树可以分为ID3算法,C4.5算法,和CART算法.ID3算法,C4.5算法可以生成二叉树或者多叉树 ...

  7. Ubuntu18.04 快速返回桌面 【快捷键】

    设置->设备->键盘->窗口->隐藏窗口 :双击重置快捷键

  8. RoR - Action Pack

    什么是Action Pack: Rest and Rails: Rest if all about resources rake routes:  print out all routes

  9. Movavi Video Editor 15 Plus(视频编辑软件) 中文版

    Movavi Video Editor 15 Plus Mac版是Movavi系列中的一款视频编辑器,Movavi Video Editor Plus 15破解版提供了全面的视频功能,另外还支持为视频 ...

  10. 谷歌将一些弱小的库从安卓代码移除Google Removes Vulnerable Library from Android

    Google this week released the November 2018 set of security patches for its Android platform, which ...