如果您使用的是Spring3.1之前版本,开启注解式处理器支持的配置为:DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter。
<="" div="">
class= "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<="" div="">
class= "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
如果您使用的Spring3.1开始的版本,建议使用RequestMappingHandlerMapping和RequestMappingHandlerAdapter。
<="" div="">
class= "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapp ing"/>
<="" div="">
class= "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdap ter"/>
视图解析器的配置
还是使用之前的org.springframework.web.servlet.view.InternalResourceViewResolver
处理器的配置
"/hello"class= "cn.javass.springmvc.hello.HelloWorldController"/>
视图页面(/WEB-INF/jsp/hello.jsp)
还是前面演示的页面,这里就不重复了
HelloWorld的运行流程
和前面第一章的HelloWorld不同之处在于:
1、HandlerMapping实现:使用DefaultAnnotationHandlerMapping(spring3.1之前)或RequestMappingHandlerMapping(spring3.1)替换之前的BeanNameUrlHandlerMapping。
注解式处理器映射会扫描spring容器中的bean,发现bean实现类上拥有@Controller或@RequestMapping注解的bean,并将它们作为处理器。
2、HandlerAdapter实现:使用AnnotationMethodHandlerAdapter(spring3.1之前)或RequestMappingHandlerAdapter(spring3.1)替换之前的SimpleControllerHandlerAdapter。
注解式处理器适配器会通过反射调用相应的功能处理方法(方法上拥有@RequestMapping注解)。
处理器定义
java代码:
- @Controller
- public class HelloWorldController {
- ……
- }
推荐使用这种方式声明处理器,它和@Service、@Repository很好的对应了我们常见的三层开发架构的组件。
java代码:
- @RequestMapping
- public class HelloWorldController {
- ……
- }
这种方式也是可以工作的,但如果在类上使用@ RequestMapping注解一般是用于窄化功能处理方法的映射的
窄化请求映射
java代码:
- @Controller
- @RequestMapping(value="/user") //①处理器的通用映射前缀
- public class HelloWorldController2 {
- @RequestMapping(value = "/hello2") //②相对于①处的映射进行窄化
- public ModelAndView helloWorld() {
- //省略实现
- }
- }
所谓窄化,就是在前面路径的基础上,继续细化的意思。比如:
http://localhost:9080/mvcexample/hello2 无法映射到HelloWorldController2的 helloWorld功能处理方法;
而http://localhost:9080/mvcexample /user/hello2是可以的
REST简介
REST(Representational State Transfer,简称REST )是什么
REST(表征状态转移)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。获得这些表征致使这些应用程序转变了其状态。随着不断获取资源的表征,客户端应用不断地在转变着其状态,所谓表征状态转移。
如果一个架构符合REST原则,就称它为RESTful架构。
REST特点
1:REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。
2:资源是由URI来指定
3:对资源的操作包括获取、创建、修改和删除资源
4:通过操作资源的表现形式来操作资源
示例
REST的优点
1:可以利用缓存Cache来提高响应速度
2:通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
3:浏览器即可作为客户端,简化软件需求
4:相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
5:不需要额外的资源发现机制
6:在软件技术演进中的长期的兼容性更好
请求映射
先来看看HttpRequest的格式
nHttpRequest信息包含六部分:
①请求方法,如GET或POST,表示提交的方式;
②URL,请求的地址信息;
③协议及版本;
④请求头信息(包括Cookie信息);
⑤回车换行;
⑥请求内容区(即请求的内容或数据),如表单提交时的参数数据、URL请求参数(?abc=123 ?后边的)等。
可以看到有①、②、④、⑥一般是可变的,因此我们可以把这些信息进行请求到处理器的功能处理方法的映射分为如下几种:
1:URL路径映射:使用URL映射请求到处理器的功能处理方法;
2:请求方法映射限定:如限定功能处理方法只处理GET请求;
3:请求参数映射限定:如限定只处理包含“abc”请求参数的请求;
4:请求头映射限定:如限定只处理“Accept=application/json”的请求。
URL路径映射
n普通URL路径映射
@RequestMapping(value={"/test1", "/user/create"}):多个URL路径可以映射到同一个处理器的功能处理方法。
nURI模板模式映射
1:@RequestMapping(value="/users/{userId}"):{×××}占位符, 请求的URL可以是 “/users/123456”或
“/users/abcd”,通过后面讲的通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。
2:@RequestMapping(value=“/users/{userId}/create”):这样也是可以的,请求的URL可以是“/users/123/create”。
3:@RequestMapping(value="/users/{userId}/topics/{topicId}"):这样也是可以的,请求的URL可以是“/users/123/topics/123”。
Ant风格的URL路径映射
1:@RequestMapping(value=“/users/**”):可以匹配“/users/abc/abc”,但“/users/123”将会被【URI模板模式映射中的“/users/{userId}”模式优先映射到】。 因为最长匹配优 先。
2:@RequestMapping(value="/product?"):可匹配“/product1”或“/producta”,但不匹配“/product”或“/productaa”;
3:@RequestMapping(value="/product*"):可匹配“/productabc”或“/product”,但不匹配“/productabc/abc”;
4:@RequestMapping(value="/product/*"):可匹配“/product/abc”,但不匹配“/productabc”;
5:@RequestMapping(value="/products/**/{productId}"):可匹配“/products/abc/abc/123”或“/products/123”,也就是Ant风格和URI模板变量风格可混用;
Ant-style 模式
匹配一个字符,如/index?可以匹配/index1,但不能匹配/index或/index12
* 匹配零个或多个字符,如/index1/*,可以匹配/index1/demo,但不匹配/index1/demo/demo
** 匹配零个或多个路径,如/index2/**:可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2/demo/demo
如果有如下模式,那Spring该选择哪一个执行呢?当请求为“/long/long”时如下所示:
/long/long
/long/**/abc
/long/**
/**
Spring的AbstractUrlHandlerMapping使用:最长匹配优先;
如请求为“/long/long” 将匹配第一个“/long/long”,但请求“/long/acd” 则将匹配 “/long/**”,如请求“/long/aa/abc”则匹配“/long/**/abc”,如请求“/abc”则将匹配“/**”
正则表达式风格的URL路径映射
从Spring3.0开始支持正则表达式风格的URL路径映射,格式为{变量名:正则表达式},这样就可以通过@PathVariable提取模式中的{×××:正则表达式匹配的值}中的×××变量了。
比如:@RequestMapping(value=“/products/{categoryCode:\\d+}-{pageNumber:\\d+}”):可以匹配“/products/123-1”,但不能匹配“/products/abc-1”,这样可以设计更加严格的规则。
正则表达式风格的URL路径映射是一种特殊的URI模板模式映射:URI模板模式映射是{userId},不能指定模板变量的数据类型,如是数字还是字符串;正则表达式风格的URL路径映射,可以指定模板变量的数据类型,可以将规则写的相当复杂。
组合使用是“或”的关系
如 @RequestMapping(value={"/test1", "/user/create"}) 组合使用是或的关系,即“/test1”或“/user/create”请求URL路径都可以映射到@RequestMapping指定的功能处理方法。
请求方法映射限定示例
@Controller
@RequestMapping("/customers/**") //①处理器的通用映射前缀
public class RequestMethodController {
@RequestMapping(value="/create", method = RequestMethod. GET)//②类级别的@RequestMapping窄化
public String showForm() {
System. out.println("===============GET");
return "customer/create";
}
@RequestMapping(value="/create", method = RequestMethod. POST)//③类级别的@RequestMapping窄化
public String submit() {
System. out.println("================POST");
return "redirect:/success";
}
}
①处理器的通用映射前缀(父路径):表示该处理器只处理匹配“/customers/**”的请求;
②对类级别的@RequestMapping进行窄化,表示showForm可处理匹配“/customers/**/create”且请求方法为“GET”的请求;
③对类级别的@RequestMapping进行窄化,表示submit可处理匹配“/customers/**/create”且请求方法为“POST”的请求。
组合使用是“或”的关系
@RequestMapping(value="/methodOr", method = {RequestMethod. POST, RequestMethod. GET}):即请求方法可以是 GET 或 POST。
提示:
1、一般浏览器只支持GET、POST请求方法,如想浏览器支持PUT、DELETE等请求方法只能模拟。
2、除了GET、POST,还有HEAD、OPTIONS、PUT、DELETE、TRACE。
3、DispatcherServlet默认开启对 GET、POST、PUT、DELETE、HEAD的支持;
4、如果需要支持OPTIONS、TRACE,请添加DispatcherServlet在web.xml的初始化参数:dispatchOptionsRequest 和 dispatchTraceRequest 为true。
请求参数映射
请求数据中有指定参数名的示例
@Controller
@RequestMapping("/parameter1") //①处理器的通用映射前缀
public class RequestParameterController1 {
//②进行类级别的@RequestMapping窄化
@RequestMapping(params="create", method=RequestMethod.GET)
public String showForm() {
System.out.println("===============showForm");
return "parameter/create";
}
//③进行类级别的@RequestMapping窄化
@RequestMapping(params="create", method=RequestMethod.POST)
public String submit() {
System.out.println("================submit");
return "redirect:/success";
}
}
示例说明
1:②@RequestMapping(params=“create”, method=RequestMethod. GET) :表示请求中有“create”的参数名且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?create”;
2:③@RequestMapping(params=“create”, method=RequestMethod. POST):表示请求中有“create”的参数名且请求方法为“POST”即可匹配;
3:此处的create请求参数名表示你请求的动作,即你想要的功能的一个标识,常见的CRUD(增删改查)我们可以使用如下请求参数名来表达:
◇(create请求参数名 且 GET请求)新增页面展示、(create请求参数名 且 POST请求)新增提交
◇(update请求参数名 且 GET请求)修改页面展示、(update请求参数名 且 POST请求)修改提交;
◇(delete请求参数名 且 GET请求)删除页面展示、(delete请求参数名 且 POST请求)删除提交;
◇(query请求参数名 且 GET请求)查询页面展示、(query请求参数名 且 POST请求)查询提交;
◇(list请求参数名 且 GET请求)列表页面展示;
◇(view请求参数名 且 GET请求)查看单条记录页面展示。
请求数据中没有指定参数名的示例
例子:@RequestMapping(params=“!create”, method=RequestMethod. GET)
1:@RequestMapping(params="!create", method=RequestMethod. GET):表示请求中没有 “create”参数名且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?abc”
n请求数据中指定参数名=值 的示例
例子:@RequestMapping(params="submitFlag=create")
n请求数据中指定参数名!=值 的示例
例子:@RequestMapping(params="submitFlag!=create", method=RequestMethod. GET)
1:上例表示请求中的参数“submitFlag!=create”且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?submitFlag=abc”。
组合使用是“且”的关系
例子:@RequestMapping(params={“test1”, “test2=create”})
1:@RequestMapping(params={"test1", "test2=create"}):表示请求中的有“test1”参数名 且 有 “test2=create”参数即可匹配,如可匹配的请求URL“http://×××/parameter3?test1&test2=create。
请求头数据映射
准备环境
浏览器:建议chrome最新版本;
插件安装步骤:
2、点击“添加至chrome”后弹出“确认安装”对话框,点击“安装”按钮即可,如图
3、安装成功后,在浏览器右上角出现如图的图标表示安装成功:
4、鼠标右击右上角的“Modify Header”图标,选择选项,打开如图
5:修改完成后,输入URL请求,你可以在chrome的“开发人员工具的”网络选项卡下,看到如图的信息表示添加请求头成功了: