博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Spring-Controller 整理研究】@RequestMapping略解
阅读量:6226 次
发布时间:2019-06-21

本文共 6148 字,大约阅读时间需要 20 分钟。

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

实验准备

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

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

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

端口号在application.properties设置为9000

server.port=9000server.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
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
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请求";    }

 

待续

转载于:https://www.cnblogs.com/syui-terra/p/10175514.html

你可能感兴趣的文章
Linqer工具
查看>>
table中超过长度的列,显示省略号
查看>>
Qtcreator中经常使用快捷键总结
查看>>
可扩展Web架构与分布式系统(转)
查看>>
KVM虚拟机的安装
查看>>
【转】PHP中require和include路径问题总结
查看>>
Android 监听apk安装替换卸载广播
查看>>
指针之——一级二级多级指针
查看>>
AndroidStudio遇到过的问题
查看>>
MySQL整体架构与内存结构
查看>>
线上centos6出现软死锁 kernel:BUG: soft lockup
查看>>
pl/sql developer 自动输入替换 光标自动定位
查看>>
HTML5学习笔记(二十三):DOM应用之动态加载脚本
查看>>
Java 中的悲观锁和乐观锁的实现
查看>>
XAMPP permissions on Mac OS X
查看>>
ffmpeg
查看>>
openGL一些概念02
查看>>
su: cannot set user id: Resource temporarily unavailable【转】
查看>>
音频变调技术
查看>>
解决App can’t be opened because it is from an unidentified developer
查看>>