springMVC4(2)请求映射全面分析
一般的,我们类定义上的路径注解起到命名空间的作用,防止不同方法的路径映射产生冲突,比如我在UserController和ArticleController下都定义了如下的方法:
这样就能有效防止冲突了,但如果我有很多个方法存在这样的冲突,是否都要在每个方法加上前缀呢?这时候我们可以选择在类路径上注解@RequestMapping来对全体方法进行区分。
除了标准的url外,@RequestMapping还支持Ant风格字符,即”?”、”*”、”**”,其中
1. “?”:匹配一个任意字符,如/user/a?,匹配user/aa,user/ab等路径
2. “*”:匹配任意字符串,如/user/a*,匹配/user下任意以a开头的路径如/user/abc,/user/aqw等
3. “**“:匹配多级路径字符串,如/user/**/list,匹配/user/user1/list,/user/1resu/list等
在这里,需要注意的是当*的位置与个数不同时,*可以代表的字符数有区别,看下面示例:
@RequestMapping("u1/*")//只能匹配u1/a,u1/b,不能匹配u1/————即此时*表示一个或多个字符 public void test(HttpServletResponse response) throws IOException{ response.getWriter().print("u1/*"); @RequestMapping("u1/**")//能够匹配u1/,u1/qq,u1/qq/ww,这里要特别注意的是,“**“能匹配零个而“*”不能 public void test(HttpServletResponse response) throws IOException{ response.getWriter().print("u1/*"); @RequestMapping("u2/a*")//能够匹配u2/a,u2/ab,u2/aqqqq等————即此时*表示零个或零个以上字符 public void test1(HttpServletResponse response) throws IOException{ response.getWriter().print("u2/a*"); }
除了使用上面风格,@RequestMapping还支持restful风格占位符的形式,假如我们需要针对特定用户查看其特定文章,restful风格路径匹配如下所示:
@Controller//注解为控制器,通过spring容器扫描,会注册为一个Bean @RequestMapping("/user/{uid}")//一级访问路径,对类中所有方法生效 public class UserController { @RequestMapping("article/{aid}") public String detail(@PathVariable("uid")Integer uid,@PathVariable("aid")Integer aid){ System.out.println( "查看id为" + uid + "的用户文章,且文章id为"+aid); return "someplace"; }
这里,如果我们想访问用户id为1,文章id为2的用户文章,就可以访问如下路径:[项目根路径]/user/1/article/2来完成。
我们使用@PathVariable(“val”)来完成对应路径中{val}的资源请求,这里的两个val名称需一致,紧接着的方法入参名字任意,我们刚刚示例了一个多路径参数绑定,假设只有一个,如下也是合法的:
@RequestMapping("user/{uid}") public String detail(@PathVariable("uid")Integer notUid){//notUid名字也能成功绑定 return "someplace"; }
此外,如果我们入参名字和url路径资源名称一致,则可以省略配置@PathVariable中的value值,如下实例也能正确绑定路径资源到入参
@RequestMapping("user/{uid}") public String detail(@PathVariable Integer uid){//notUid名字也能成功绑定 return "someplace"; }
@RequestMapping("test/**") public void test2(HttpServletResponse response) throws IOException{ response.getWriter().print("test/**"); @RequestMapping("test/*") public void test3(HttpServletResponse response) throws IOException{ response.getWriter().print("test/*"); @RequestMapping("test/*/**") public void test4(HttpServletResponse response) throws IOException{ response.getWriter().print("test/*/**"); @RequestMapping("test/*/*") public void test5(HttpServletResponse response) throws IOException{ response.getWriter().print("test/*/*"); @RequestMapping("test/1/*") public void test6(HttpServletResponse response) throws IOException{ response.getWriter().print("test/1/*"); @RequestMapping("test/1/2") public void test7(HttpServletResponse response) throws IOException{ response.getWriter().print("test/1/2"); }
直接看上面匹配会觉得很乱,我们直接看下面的测试:
@RequestMapping("test/1/2") public void test7(HttpServletResponse response) throws IOException{ response.getWriter().print("test/1/2"); @RequestMapping("test/1/{id}") public void test8(HttpServletResponse response,@PathVariable Integer id ) throws IOException{ response.getWriter().print("test/1/(myId=)" + id ); @RequestMapping("test/1/a") public void test7(HttpServletResponse response) throws IOException{ response.getWriter().print("test/1/a"); }
从上一个实例的所有路径映射中,我们测试出test/1/2是最精确的。但我们根据添加了占位符映射,在游览器输入test/1/2,此时游览器返回test/1/(myId=)2,即占位符的优先级比普通字符串的优先级更高!但如果我们此时输入test/1/a。程序不会因为我们的在方法入参中id映射为Integer类型而放弃匹配,占位符的优先级依然比字符(串)a的优先级高,但由于“a”不能转化为Integer类型,所以服务器会返回400错误
除了使用url外,我们还能通过请求参数、请求方法、或请求头进行映射
我们先看看@RequestMapping的完整属性列表:
其中,consumes, produces使用content-type信息进行过滤信息;headers中可以使用content-type进行过滤和判断。
在前面的使用中,我们发现并没有指定value属性,直接在括号里输入字符串也能向value属性赋值,这是因为在java注解中不加其他属性,直接赋值必定是针对注解的value成员,如果该注解没有名为value的成员,则会报错
下面我们先看几个示例:
@RequestMapping(value = "testa",method = RequestMethod.POST,headers = "content-type=text/*")
表示映射路径为testa,请求方法必须为POST方法(如果我们用post发出请求,会返回错误信息HTTP Status 405 - Request method ‘GET’ not supported),headers部分表示请求头信息中必须包含等号后相应部分内容,*匹配任意字符串
表示方法匹配的请求需要请求头中Accept部分包含”application/json“,同时在响应时,会将返回内容同时设置为”application/json‘’
@RequestMapping(value = "testd",method = RequestMethod.GET,params = {"id1","id2"}) public void test12(HttpServletResponse response,Integer id1,Integer id2) throws IOException{ response.getWriter().print(id1 + "——" + id2); }
示例表示入参需包含参数名为id1,id2的两个参数,这里如果我输入:
1. http://localhost:8080/springMVC/user/testd—-
2. http://localhost:8080/springMVC/user/testd?id1=1—报404错误
3. ttp://localhost:8080/springMVC/user/testd?id1=1 id2=2—-返回1——2
4. ttp://localhost:8080/springMVC/user/testd?id1=1 id2=2 id3=3—-返回1——2
从以上我们可以看出,只有具有相应参数的才能完成映射,且可以有除了params中要求以外的参数,如id3。
{“param1=value1”,”param2”} 请求中需要包含param1参数和param2参数,且param1的值必须为value1
Spring项目中修改javamelody映射url以及其它参数失效的问题 首先,servlet3.0支持模块化,在jar包中如果有web-fragmenet.xml,则servlet容器会先加载web.xml里的listener、filter和servlet,再加载web-fragment.xml里的组件。关于模块化的介绍:
相关文章
- 【说站】python ChainMap如何管理映射列表
- java编译报错提示编码GBK的不可映射字符啥意思_java字符串编码转换
- unity不同骨骼模型公用动画_为何unity的模组映射为0
- 数据库二级映射是什么_内存映射技术
- 将非数字的用户ID映射到位图的方案探讨
- 【Android 安装包优化】资源混淆 ( resources.arsc 资源映射表混淆 | resources.arsc 资源映射表二进制格式分析 | 混淆全局字符串池和资源名称字符串池 )
- 【Linux 内核 内存管理】内存映射相关数据结构 ④ ( vm_area_struct 结构体成员分析 | vm_ops 成员 | vm_operations_struct 结构体成员分析 )
- 【Linux 内核 内存管理】内存管理系统调用 ④ ( 代码示例 | mmap 创建内存映射 | munmap 删除内存映射 )
- 【Linux 内核 内存管理】分区伙伴分配器 ② ( free_area 空闲区域结构体源码 | 分配标志位 | GFP_ZONE_TABLE 标志位区域类型映射表 |分配标志位对应的内存区域类型 )
- Java数据持久层框架 MyBatis之API学习三(XML 映射配置文件)详解编程语言
- Java Servlet Filter的两种映射方式
- Mysql终结点映射:解锁新的可能性(mysql终结点映射器)
- 内核Linux内核存储映射技术(存储映射给linux)
- MySQL映射:简单方法转换关系数据库和对象模型(mysql映射)
- Linux下ARP添加静态映射实践(linux arp 添加)
- 从Idea中将Oracle数据库映射到前端(idea映射oracle)
- MySQL 数据库可不必强制写映射(mysql 不写映射)
- python映射列表实例分析