springMVC(2)请求映射全面分析

在springMVC的控制器中,我们常使用@RequestMapping来完成我们的请求映射,我们可以在类定义上和方法定义上使用注解,其配置的路径将为类中定义的所有方法的父路径,如上篇实例中的/user(类)/hello(方法)。

一般的,我们类定义上的路径注解起到命名空间的作用,防止不同方法的路径映射产生冲突,比如我在UserController和ArticleController下都定义了如下的方法:

@RequestMapping("list")
public void list(){
    ....
}

一个list映射路径,这时候springMVC就不知道该将请求交给到哪个方法处理。当然,我们也能在方法上进行二级路径配置区分:

/*************UserController***********/
@RequestMapping("user/list")
public void list(){
    ....
}
/*************ArticleController***********/
@RequestMapping("article/list")
public void list(){
    ....
}

这样就能有效防止冲突了,但如果我有很多个方法存在这样的冲突,是否都要在每个方法加上前缀呢?这时候我们可以选择在类路径上注解@RequestMapping来对全体方法进行区分。

通过url进行映射

1. Ant风格字符匹配

除了标准的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*");
}

2. restful占位符匹配

除了使用上面风格,@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";
    }

3. 优先匹配规则

url还有如下两个常见匹配准则:最长最精确优先匹配占位符优先匹配

1. 最长最精确优先匹配

下面我们来看一个匹配实例:

@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");
}

直接看上面匹配会觉得很乱,我们直接看下面的测试:

测试 匹配结果
test/a 匹配test/*而不匹配test/**(更精确优先匹配)
test/a/a/aa/a 匹配test/**而不匹配test/*/**,(在多层匹配中,**比*/**更精确)
test/a/a 匹配test/*/*,因为/*/*比**精确
test/1/a 匹配test/1/*,因为/1/*比/*/*精确
test/1/2 匹配test/1/2,这是完全匹配

2. 占位符优先匹配原则

占位符是指@PathVariable等路径资源占位符,下面我们在看一个实例

@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错误

通过HTTP其它请求资源映射

除了使用url外,我们还能通过请求参数、请求方法、或请求头进行映射

我们先看看@RequestMapping的完整属性列表:

属性 说明
value 指定请求的实际地址, 比如 /action/info之类。
method 指定请求的method类型, GET、POST、PUT、DELETE等
consumes 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
params 指定request中必须包含某些参数值是,才让该方法处理
headers 指定request中必须包含某些指定的header值,才能让该方法处理请求

其中,consumes, produces使用content-type信息进行过滤信息;headers中可以使用content-type进行过滤和判断。

在前面的使用中,我们发现并没有指定value属性,直接在括号里输入字符串也能向value属性赋值,这是因为在java注解中不加其他属性,直接赋值必定是针对注解的value成员,如果该注解没有名为value的成员,则会报错

下面我们先看几个示例:

示例1:vmethod,headers

@RequestMapping(value = "testa",method = RequestMethod.POST,headers = "content-type=text/*")

表示映射路径为testa,请求方法必须为POST方法(如果我们用post发出请求,会返回错误信息HTTP Status 405 - Request method ‘GET’ not supported),headers部分表示请求头信息中必须包含等号后相应部分内容,*匹配任意字符串

示例2:consumes

@RequestMapping(value = "testb", consumes="application/json") 

表示方法仅匹配request Content-Type为“application/json”类型的请求。

示例3:produces

@RequestMapping(value = "/testc", produces="application/json")

表示方法匹配的请求需要请求头中Accept部分包含”application/json“,同时在响应时,会将返回内容同时设置为”application/json‘’

示例4:params

@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。

在params的常见映射规则如下:

示例规则 说明
”param1” 请求必须包含名为param1的参数
“!param1” 请求中不能包含名为param1的参数
“param1!=value1 请求中必须包含param1参数,但其值不能为value1
{“param1=value1”,”param2”} 请求中需要包含param1参数和param2参数,且param1的值必须为value1
时间: 2024-10-18 06:16:29

springMVC(2)请求映射全面分析的相关文章

05.SpringMVC之请求映射

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. @RequestMapping注解有六个属性,下面进行详细的说明. value:指定请求的实际地址,指定的地址可以是URI Template模式. value的uri值为以下三类: A) 可以指定为普通的具体值: B)  可以指定为含有某变量的一类值: C) 可以指定为含正则表达式的一类值? method:指定请求的method类型,GET.POST

springmvc学习(二)——使用RequestMapper请求映射

本次内容是@RequestMapping,后面会有实例代码 Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求在控制器的类定义及方法定义处都可标注@RequestMapping @RequestMapping不仅可以修饰类,还可以修饰方法.类定义处:提供初步的请求映射信息.相对于 WEB 应用的根目录方法处:提供进一步的细分映射信息.相对于类定义处的 URL.若类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于WEB

SpringMVC——请求映射

SpringMVC中,如何处理请求是很重要的任务.请求映射都会使用@RequestMapping标注.其中,类上的标注相当于一个前缀,表示该处理器是处理同一类请求:方法上的标注则更加细化.如,类的标注可能是"user",表示全部都是与用户相关的操作:具体到方法可能有"create""update""delete"等,分别表示对用户进行哪一类操作. package cn.javass.chapter6.web.controlle

【spring springmvc】springmvc使用注解声明控制器与请求映射

目录 概述 壹:注解说明 贰:实现注解声明控制器与请求映射 一:使用controller 二:配置包扫描与视图解析器 1.配置包扫描 2.配置试图解析器 三:配置部署描述符 1.读取spring-mvc.xml文件 2.配置匹配映射 四:建立html文件 叁:配置tomcat 一:配置本地tomcat 二:配置maven内置tomcat 肆:结果及问题 一:tomcat启动示意图: 二:结果 三:问题 伍:结构及源码 一:目录结构 二:源码 作者有话 概述 注解: 在Spring中尽管使用XML

【springmvc框架】(一)原理分析

SpringMVC 运行流程分析 在整个 Spring MVC 框架中, DispatcherServlet 处于核心位置,负责协调和组织不同组件以完成请求处理并返回响应的工作. SpringMVC 处理请求过程: 1.发送请求至DispatcherServlet 1)若不匹配请求映射路径(在 web.xml 中指定) 则判断是否配置<mvc:default-servlet-handler/>? ① 若已配置,则显示目标资源. ② 若未配置,则显示404页面,同时控制台打印"No M

SpringMVC核心分发器DispatcherServlet分析[附带源码分析]

SpringMVC核心分发器DispatcherServlet分析[附带源码分析] 目录 前言 DispatcherServlet初始化过程 DispatcherServlet处理请求过程 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html 本文将分析SpringMVC的核心分发器Dispa

SpringMVC核心分发器DispatcherServlet分析

本文将分析SpringMVC的核心分发器DispatcherServlet的初始化过程以及处理请求的过程,让读者了解这个入口Servlet的作用. DispatcherServlet初始化过程 在分析DispatcherServlet之前,我们先看下DispatcherServlet的继承关系. HttpSerlvetBean继承自HttpServlet. HttpServletBean覆写了init方法,对初始化过程做了一些处理. 我们来看下init方法到底做了什么: <servlet> &

SpringMVC RequestMapping &amp; 请求参数

SpringMVC 概述 Spring 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一 Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架 Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口. 支持 REST 风格的 URL 请求 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性 HelloWorld 步骤: –加入 jar 包 –在 web.xml 中配置

struts2请求过程源代码分析

struts2请求过程源代码分析 Struts2是Struts社区和WebWork社区的共同成果.我们甚至能够说,Struts2是WebWork的升级版.他採用的正是WebWork的核心,所以.Struts2并非一个不成熟的产品,相反.构建在WebWork基础之上的Struts2是一个执行稳定.性能优异.设计成熟的WEB框架. 我这里的struts2源代码是从官网下载的一个最新的struts-2.3.15.1-src.zip.将其解压就可以. 里面的文件夹页文件很的多,我们仅仅须要定位到stru