spring mvc methodMvc中,RequestMethod可以同时支持POST GET访问么

SpringMVC开启CORS支持 - 简书
SpringMVC开启CORS支持
浏览器出于安全考虑,限制了JS发起跨站请求,使用XHR对象发起请求必须遵循同源策略(SOP:Same Origin Policy),跨站请求会被浏览器阻止,这对开发者来说是很痛苦的一件事,尤其是要开发前后端分离的应用时。
在现代化的Web开发中,不同网络环境下的资源数据共享越来越普遍,同源策略可以说是在一定程度上限制了Web API的发展。
简单的说,CORS就是为了AJAX能够安全跨域而生的。至于CORS的安全性研究,本文不做探讨。
如何使用?CORS的HTTP头
初始项目准备
CorsFilter: 过滤器阶段的CORS
CorsInterceptor: 拦截器阶段的CORS
@CrossOrigin:Handler阶段的CORS
追求极致的开发体验:整合第三方CORSFilter
示例代码下载
名词解释:跨域资源共享(Cross-Origin Resource Sharing)
概念:是一种跨域机制、规范、标准,怎么叫都一样,但是这套标准是针对服务端的,而浏览器端只要支持HTML5即可。
作用:可以让服务端决定哪些请求源可以进来拿数据,所以服务端起主导作用(所以出了事找后台程序猿,无关前端^ ^)
常用场景:
前后端完全分离的应用,比如Hybrid App
开放式只读API,JS能够自由访问,比如地图、天气、时间……
如何使用?CORS的HTTP头
要实现CORS跨域其实非常简单,说白了就是在服务端设置一系列的HTTP头,主要分为请求头和响应头,在请求和响应时加上这些HTTP头即可轻松实现CORS
请求头和响应头信息都是在服务端设置好的,一般在Filter阶段设置,浏览器端不用关心,唯一要设置的地方就是:跨域时是否要携带cookie
HTTP请求头:
Origin: ”http://localhost:3000“
#这两个属性只出现在预检请求中,即OPTIONS请求
Access-Control-Request-Method: ”POST“
Access-Control-Request-Headers: ”content-type“
HTTP响应头:
#允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
Access-Control-Allow-Origin: ”http://localhost:3000“
#允许访问的头信息
Access-Control-Expose-Headers: "Set-Cookie"
#预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
Access-Control-Max-Age: ”1800”
#允许Cookie跨域,在做登录校验的时候有用
Access-Control-Allow-Credentials: “true”
#允许提交请求的方法,*表示全部允许
Access-Control-Allow-Methods:GET,POST,PUT,DELETE,PATCH
初始项目准备
补充一下,对于简单跨域和非简单跨域,可以这么理解:
简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain
反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求
首先新建一个静态web项目,定义三种类型的请求:简单跨域请求,非简单跨域请求,带Cookie信息的请求(做登录校验)。代码如下:
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&跨域demo&/title&
&link rel="stylesheet" href="node_modules/amazeui/dist/css/amazeui.min.css"&
&body class="am-container"&
&!--简单跨域--&
&button class="am-btn am-btn-primary" onclick="getUsers(this)"&
简单跨域: 获取用户列表
&p class="am-text-danger"&&/p&
&!--非简单跨域--&
&button class="am-btn am-btn-primary" onclick="addUser(this)"&
非简单跨域: 添加用户(JSON请求)
&input type="text" placeholder="用户名"&
&p class="am-text-danger"&&/p&
&!--检查是否登录--&
&button class="am-btn am-btn-primary am-margin-right" onclick="checkLogin(this)"&
&p class="am-text-danger"&&/p&
&!--登录--&
&button class="am-btn am-btn-primary" onclick="login(this)"&
&input type="text" placeholder="用户名"&
&p class="am-text-danger"&&/p&
&script src="node_modules/jquery/dist/jquery.min.js"&&/script&
&script src="node_modules/amazeui/dist/js/amazeui.js"&&/script&
function getUsers(btn) {
var $btn = $(btn);
type: 'get',
url: 'http://localhost:8080/api/users',
contentType: "application/charset=UTF-8"
function (obj) {
$btn.next('p').html(JSON.stringify(obj));
function () {
$btn.next('p').html('error...');
function addUser(btn) {
var $btn = $(btn);
var name = $btn.next('input').val();
if (!name) {
$btn.next('input').next('p').html('用户名不能为空');
type: 'post',
url: 'http://localhost:8080/api/users',
contentType: "application/charset=UTF-8",
data: name,
dataType: 'json'
function (obj) {
$btn.next('input').next('p').html(JSON.stringify(obj));
function () {
$btn.next('input').next('p').html('error...');
function checkLogin(btn) {
var $btn = $(btn);
type: 'get',
url: 'http://localhost:8080/api/user/login',
contentType: "application/charset=UTF-8",
xhrFields: {
withCredentials: true
function (obj) {
$btn.next('p').html(JSON.stringify(obj));
function () {
$btn.next('p').html('error...');
function login(btn) {
var $btn = $(btn);
var name = $btn.next('input').val();
if (!name) {
$btn.next('input').next('p').html('用户名不能为空');
type: 'post',
url: 'http://localhost:8080/api/user/login',
contentType: "application/charset=UTF-8",
data: name,
dataType: 'json',
xhrFields: {
withCredentials: true
function (obj) {
$btn.next('input').next('p').html(JSON.stringify(obj));
function () {
$btn.next('input').next('p').html('error...');
然后启动web项目(这里推荐一个所见即所得工具:browser-sync)
browser-sync start --server --files "*.html"
接来下,做服务端的事情,新建一个SpringMVC项目,这里推荐一个自动生成Spring种子项目的网站:
项目结构如下:
在pom.xml中引入lombok和guava
&dependency&
&groupId&com.google.guava&/groupId&
&artifactId&guava&/artifactId&
&version&19.0&/version&
&/dependency&
&dependency&
&groupId&org.projectlombok&/groupId&
&artifactId&lombok&/artifactId&
&version&1.16.8&/version&
&/dependency&
模拟数据源:UserDB
public class UserDB {
public static Cache&String, User& userdb = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.DAYS).build();
String id1 = UUID.randomUUID().toString();
String id2 = UUID.randomUUID().toString();
String id3 = UUID.randomUUID().toString();
userdb.put(id1, new User(id1, "jear"));
userdb.put(id2, new User(id2, "tom"));
userdb.put(id3, new User(id3, "jack"));
编写示例控制器:UserController
@RestController
@RequestMapping("/users")
public class UserController {
@RequestMapping(method = RequestMethod.GET)
List&User& getList() {
return Lists.newArrayList(userdb.asMap().values());
@RequestMapping(method = RequestMethod.POST)
List&String& add(@RequestBody String name) {
if (userdb.asMap().values().stream().anyMatch(user -& user.getName().equals(name))) {
return Lists.newArrayList("添加失败, 用户名'" + name + "'已存在");
String id = UUID.randomUUID().toString();
userdb.put(id, new User(id, name));
return Lists.newArrayList("添加成功: " + userdb.getIfPresent(id));
编写示例控制器:UserLoginController
@RestController
@RequestMapping("/user/login")
public class UserLoginController {
@RequestMapping(method = RequestMethod.GET)
Object getInfo(HttpSession session) {
Object object = session.getAttribute("loginer");
return object == null ? Lists.newArrayList("未登录") :
@RequestMapping(method = RequestMethod.POST)
List&String& login(HttpSession session, @RequestBody String name) {
Optional&User& user = userdb.asMap().values().stream().filter(user1 -& user1.getName().equals(name)).findAny();
if (user.isPresent()) {
session.setAttribute("loginer", user.get());
return Lists.newArrayList("登录成功!");
return Lists.newArrayList("登录失败, 找不到用户名:" + name);
最后启动服务端项目
mvn clean package
debug模式启动Application
到这里,主要工作都完成了,打开浏览器,访问静态web项目,打开控制台,发现Ajax请求无法获取数据,这就是同源策略的限制
下面我们一步步来开启服务端的CORS支持
CorsFilter: 过滤器阶段的CORS
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
public FilterRegistrationBean filterRegistrationBean() {
// 对响应头进行CORS授权
MyCorsRegistration corsRegistration = new MyCorsRegistration("/**");
corsRegistration.allowedOrigins(CrossOrigin.DEFAULT_ORIGINS)
.allowedMethods(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
.allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS)
.exposedHeaders(HttpHeaders.SET_COOKIE)
.allowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS)
.maxAge(CrossOrigin.DEFAULT_MAX_AGE);
// 注册CORS过滤器
UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
configurationSource.registerCorsConfiguration("/**", corsRegistration.getCorsConfiguration());
CorsFilter corsFilter = new CorsFilter(configurationSource);
return new FilterRegistrationBean(corsFilter);
现在测试一下“简单跨域”和“非简单跨域”,已经可以正常响应了
浏览器图片
再来测试一下 “登录校验” 和 “登录”,看看cookie是否能正常跨域
浏览器图片
如果把服务端的allowCredentials设为false,或者ajax请求中不带{withCredentials: true},那么登录校验永远都是未登录,因为cookie没有在浏览器和服务器之间传递
CorsInterceptor: 拦截器阶段的CORS
既然已经有了Filter级别的CORS,为什么还要CorsInterceptor呢?因为控制粒度不一样!Filter是任意Servlet的前置过滤器,而Inteceptor只对DispatcherServlet下的请求拦截有效,它是请求进入Handler的最后一道防线,如果再设置一层Inteceptor防线,可以增强安全性和可控性。
关于这个阶段的CORS,不得不吐槽几句,Spring把CorsInteceptor写死在了拦截器链上的最后一个,也就是说如果我有自定义的Interceptor,请求一旦被我自己的拦截器拦截下来,则只能通过CorsFilter授权跨域,压根走不到CorsInterceptor,至于为什么,下面会讲到。
所以说CorsInterceptor是专为授权Handler中的跨域而写的。
废话不多说,直接上代码:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
public FilterRegistrationBean corsFilterRegistrationBean() {
// 对响应头进行CORS授权
MyCorsRegistration corsRegistration = new MyCorsRegistration("/**");
this._configCorsParams(corsRegistration);
// 注册CORS过滤器
UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
configurationSource.registerCorsConfiguration("/**", corsRegistration.getCorsConfiguration());
CorsFilter corsFilter = new CorsFilter(configurationSource);
return new FilterRegistrationBean(corsFilter);
public void addCorsMappings(CorsRegistry registry) {
// 配置CorsInterceptor的CORS参数
this._configCorsParams(registry.addMapping("/**"));
private void _configCorsParams(CorsRegistration corsRegistration) {
corsRegistration.allowedOrigins(CrossOrigin.DEFAULT_ORIGINS)
.allowedMethods(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
.allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS)
.exposedHeaders(HttpHeaders.SET_COOKIE)
.allowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS)
.maxAge(CrossOrigin.DEFAULT_MAX_AGE);
打开浏览器,效果和上面一样
@CrossOrigin:Handler阶段的CORS
如果把前面的代码认真写一遍,应该已经发现这个注解了,这个注解是用在控制器方法上的,其实Spring在这里用的还是CorsInterceptor,做最后一层拦截,这也就解释了为什么CorsInterceptor永远是最后一个执行的拦截器。
这是最小控制粒度了,可以精确到某个请求的跨域控制
// 先把WebConfig中前两阶段的配置注释掉,再到这里加跨域注解
@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(method = RequestMethod.GET)
List&User& getList() {
return Lists.newArrayList(userdb.asMap().values());
打开浏览器,发现只有第一个请求可以正常跨域
Handler跨域
三个阶段的CORS配置顺序是后面叠加到前面,而不是后面完全覆盖前面的,所以在设计的时候,每个阶段如何精确控制CORS,还需要在实践中慢慢探索……
追求更好的开发体验:整合第三方CORSFilter
对这个类库的使用和分析将在下一篇展开
喜欢用这个CORSFilter主要是因为它支持CORS配置文件,能够自动读取classpath下的cors.properties,还有file watching的功能
示例代码下载SpringMVC3强大的请求映射规则详解
第六章 注解式控制器详解——跟着开涛学SpringMVC - 开涛的博客(扫一扫头像关注公众号,掌握最新技术&架构) - ITeye技术网站
博客分类:
声明:本系列都是原创内容,觉得好就顶一个,让更多人知道!!写博客不容易,写原创更不容易!!
6.5、请求映射
处理器定义好了,那接下来我们应该定义功能处理方法,接收用户请求处理并选择视图进行渲染。首先我们看一下图6-1:
http请求信息包含六部分信息:
①请求方法,如GET或POST,表示提交的方式;
②URL,请求的地址信息;
③协议及版本;
④请求头信息(包括Cookie信息);
⑤回车换行(CRLF);
⑥请求内容区(即请求的内容或数据),如表单提交时的参数数据、URL请求参数(?abc=123 ?后边的)等。
想要了解HTTP/1.1协议,请访问。
那此处我们可以看到有①、②、④、⑥一般是可变的,因此我们可以这些信息进行请求到处理器的功能处理方法的映射,因此请求的映射分为如下几种:
URL路径映射:使用URL映射请求到处理器的功能处理方法;
请求方法映射限定:如限定功能处理方法只处理GET请求;
请求参数映射限定:如限定只处理包含“abc”请求参数的请求;
请求头映射限定:如限定只处理“Accept=application/json”的请求。
接下来看看具体如何映射吧。
6.5.1、URL路径映射
6.5.1.1、普通URL路径映射
@RequestMapping(value={"/test1", "/user/create"}):多个URL路径可以映射到同一个处理器的功能处理方法。
6.5.1.2、URI模板模式映射
@RequestMapping(value="/users/{userId}"):{×××}占位符, 请求的URL可以是 “/users/123456”或
“/users/abcd”,通过6.6.5讲的通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。
@RequestMapping(value="/users/{userId}/create"):这样也是可以的,请求的URL可以是“/users/123/create”。
@RequestMapping(value="/users/{userId}/topics/{topicId}"):这样也是可以的,请求的URL可以是“/users/123/topics/123”。
6.5.1.3、Ant风格的URL路径映射
@RequestMapping(value="/users/**"):可以匹配“/users/abc/abc”,但“/users/123”将会被【URI模板模式映射中的“/users/{userId}”模式优先映射到】【详见4.14的最长匹配优先】。
@RequestMapping(value="/product?"):可匹配“/product1”或“/producta”,但不匹配“/product”或“/productaa”;
@RequestMapping(value="/product*"):可匹配“/productabc”或“/product”,但不匹配“/productabc/abc”;
@RequestMapping(value="/product/*"):可匹配“/product/abc”,但不匹配“/productabc”;
@RequestMapping(value="/products/**/{productId}"):可匹配“/products/abc/abc/123”或“/products/123”,也就是Ant风格和URI模板变量风格可混用;
此处需要注意的是【4.14中提到的最长匹配优先】,Ant风格的模式请参考4.14。
6.5.1.4、正则表达式风格的URL路径映射
从Spring3.0开始支持正则表达式风格的URL路径映射,格式为{变量名:正则表达式},这样我们就可以通过6.6.5讲的通过@PathVariable提取模式中的{×××:正则表达式匹配的值}中的×××变量了。
@RequestMapping(value="/products/{categoryCode:\\d+}-{pageNumber:\\d+}"):可以匹配“/products/123-1”,但不能匹配“/products/abc-1”,这样可以设计更加严格的规则。
正则表达式风格的URL路径映射是一种特殊的URI模板模式映射:
URI模板模式映射是{userId},不能指定模板变量的数据类型,如是数字还是字符串;
正则表达式风格的URL路径映射,可以指定模板变量的数据类型,可以将规则写的相当复杂。
6.5.1.5、组合使用是“或”的关系
如 @RequestMapping(value={"/test1", "/user/create"}) 组合使用是或的关系,即“/test1”或“/user/create”请求URL路径都可以映射到@RequestMapping指定的功能处理方法。
以上URL映射的测试类为:cn.javass.chapter6.web.controller.mapping.MappingController.java。
到此,我们学习了Spring
Web MVC提供的强大的URL路径映射,而且可以实现非常复杂的URL规则。Spring Web MVC不仅仅提供URL路径映射,还提供了其他强大的映射规则。接下来我们看一下请求方法映射限定吧。
6.5.2、请求方法映射限定
一般我们熟悉的表单一般分为两步:第一步展示,第二步提交,如4.9、SimpleFormController那样,那如何通过@RequestMapping来实现呢?
6.5.2.1、请求方法映射限定
我们熟知的,展示表单一般为GET请求方法;提交表单一般为POST请求方法。但6.5.1节讲的URL路径映射方式对任意请求方法是全盘接受的,因此我们需要某种方式来告诉相应的功能处理方法只处理如GET请求方法的请求或POST请求方法的请求。
接下来我们使用@RequestMapping来实现SimpleFormController的功能吧。
package cn.javass.chapter6.web.controller.
//省略import
@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”的请求。
6.5.2.2、组合使用是“或”的关系
@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。
请求方法的详细使用请参考RESTful架构风格一章。
以上请求方法映射限定测试类为:cn.javass.chapter6.web.controller.method.RequestMethodController。
6.5.3、请求参数数据映射限定
6.5.3.1、请求数据中有指定参数名
package cn.javass.chapter6.web.controller.
//省略import
@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";
②@RequestMapping(params="create", method=RequestMethod.GET) :表示请求中有“create”的参数名且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?create”;
③@RequestMapping(params="create", method=RequestMethod.POST):表示请求中有“create”的参数名且请求方法为“POST”即可匹配;
此处的create请求参数名表示你请求的动作,即你想要的功能的一个标识,常见的CRUD(增删改查)我们可以使用如下请求参数名来表达:
◇(create请求参数名 且 GET请求方法) 新增页面展示、(create请求参数名 且 POST请求方法)新增提交;
◇(update请求参数名 且 GET请求方法) 新增页面展示、(update请求参数名 且 POST请求方法)新增提交;
◇(delete请求参数名 且 GET请求方法) 新增页面展示、(delete请求参数名 且 POST请求方法)新增提交;
◇(query请求参数名 且 GET请求方法) 新增页面展示、(query请求参数名 且 POST请求方法) 新增提交;
◇(list请求参数名 且 GET请求方法) 列表页面展示;
◇(view请求参数名 且 GET请求方法) 查看单条记录页面展示。
6.5.3.2、请求数据中没有指定参数名
//请求参数不包含 create参数名
@RequestMapping(params="!create", method=RequestMethod.GET)//进行类级别的@RequestMapping窄化
@RequestMapping(params="!create", method=RequestMethod.GET):表示请求中没有“create”参数名且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?abc”。
6.5.3.3、请求数据中指定参数名=值
package cn.javass.chapter6.web.controller.
//省略import
@Controller
@RequestMapping("/parameter2")
//①处理器的通用映射前缀
public class RequestParameterController2 {
//②进行类级别的@RequestMapping窄化
@RequestMapping(params="submitFlag=create", method=RequestMethod.GET)
public String showForm() {
System.out.println("===============showForm");
return "parameter/create";
//③进行类级别的@RequestMapping窄化
@RequestMapping(params="submitFlag=create", method=RequestMethod.POST)
public String submit() {
System.out.println("===============submit");
return "redirect:/success";
②@RequestMapping(params="submitFlag=create", method=RequestMethod.GET):表示请求中有“submitFlag=create”请求参数且请求方法为“GET”即可匹配,如请求URL为;
③@RequestMapping(params="submitFlag=create", method=RequestMethod.POST):表示请求中有“submitFlag=create”请求参数且请求方法为“POST”即可匹配;
此处的submitFlag=create请求参数表示你请求的动作,即你想要的功能的一个标识,常见的CRUD(增删改查)我们可以使用如下请求参数名来表达:
◇(submitFlag=create请求参数名 且 GET请求方法) 新增页面展示、(submitFlag=create请求参数名 且 POST请求方法) 新增提交;
◇(submitFlag=update请求参数名 且 GET请求方法) 新增页面展示、(submitFlag=update请求参数名 且 POST请求方法) 新增提交;
◇(submitFlag=delete请求参数名 且 GET请求方法) 新增页面展示、(submitFlag=delete请求参数名 且 POST请求方法) 新增提交;
◇(submitFlag=query请求参数名 且 GET请求方法) 新增页面展示、(submitFlag=query请求参数名 且 POST请求方法) 新增提交;
◇(submitFlag=list请求参数名 且 GET请求方法) 列表页面展示;
◇(submitFlag=view请求参数名 且 GET请求方法) 查看单条记录页面展示。
6.5.3.4、请求数据中指定参数名!=值
//请求参数submitFlag 不等于 create
@RequestMapping(params="submitFlag!=create", method=RequestMethod.GET)
@RequestMapping(params="submitFlag!=create", method=RequestMethod.GET):表示请求中的参数“submitFlag!=create”且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?submitFlag=abc”。
6.5.3.5、组合使用是“且”的关系
@RequestMapping(params={"test1", "test2=create"})
//②进行类级别的@RequestMapping窄化
@RequestMapping(params={"test1", "test2=create"}):表示请求中的有“test1”参数名 且 有“test2=create”参数即可匹配,如可匹配的请求URL“http://×××/parameter3?test1&test2=create。
以上请求参数数据映射限定测试类为:cn.javass.chapter6.web.controller.method包下的RequestParameterController1、RequestParameterController2、RequestParameterController3。
6.5.4、请求头数据映射限定
6.5.4.1、准备环境
浏览器:建议chrome最新版本;
插件:ModHeader
安装地址:
插件安装步骤:
1、打开,如图6-2
2、点击“添加至chrome”后弹出“确认安装”对话框,点击“安装”按钮即可,如图6-3:
3、安装成功后,在浏览器右上角出现如图6-4的图标表示安装成功:
4、鼠标右击右上角的“Modify Header”图标,选择选项,打开如图6-5:
7、修改完成后,输入URL请求,你可以在chrome的“开发人员工具的”网络选项卡下,看到如图6-7的信息表示添加请求头成功了:
到此我们的工具安装完毕,接下来看看如何使用请求头数据进行映射限定。
6.5.4.2、请求头数据中有指定参数名
@RequestMapping(value="/header/test1", headers = "Accept"):表示请求的URL必须为“/header/test1”
且 请求头中必须有Accept参数才能匹配。
@RequestMapping(value="/header/test1", headers = "abc"):表示请求的URL必须为“/header/test1”
且 请求头中必须有abc参数才能匹配,如图6-8时可匹配。
6.5.4.3、请求头数据中没有指定参数名
@RequestMapping(value="/header/test2", headers = "!abc"):表示请求的URL必须为“/header/test2”
且 请求头中必须没有abc参数才能匹配。(将Modify Header的abc参数值删除即可)。
6.5.4.4、请求头数据中指定参数名=值
@RequestMapping(value="/header/test3", headers = "Content-Type=application/json"):表示请求的URL必须为“/header/test3” 且 请求头中必须有“Content-Type=application/json”参数即可匹配。(将Modify Header的Content-Type参数值改为“application/json”即可);
当你请求的URL为“/header/test3” 但 如果请求头中没有或不是“Content-Type=application/json”参数(如“text/html”其他参数),将返回“HTTP Status 415”状态码【表示不支持的媒体类型(Media Type),也就是MIME类型】,即我们的功能处理方法只能处理application/json的媒体类型。
@RequestMapping(value="/header/test4", headers = "Accept=application/json"):表示请求的URL必须为“/header/test4” 且 请求头中必须有“Accept =application/json”参数即可匹配。(将Modify Header的Accept参数值改为“application/json”即可);
当你请求的URL为“/header/test4” 但 如果请求头中没有“Accept=application/json”参数(如“text/html”其他参数),将返回“HTTP Status 406”状态码【不可接受,服务器无法根据Accept头的媒体类型为客户端生成响应】,即客户只接受“application/json”媒体类型的数据,即我们的功能处理方法的响应只能返回“application/json”媒体类型的数据。
@RequestMapping(value="/header/test5", headers = "Accept=text/*") :表示请求的URL必须为“/header/test5” 且 请求头中必须有如“Accept=text/plain”参数即可匹配。(将Modify Header的Accept参数值改为“text/plain”即可);
Accept=text/*:表示主类型为text,子类型任意,如“text/plain”、“text/html”等都可以匹配。
@RequestMapping(value="/header/test6", headers = "Accept=*/*") :表示请求的URL必须为“/header/test6” 且 请求头中必须有任意Accept参数即可匹配。(将Modify Header的Accept参数值改为“text/html”或“application/xml”等都可以)。
Accept=*/*:表示主类型任意,子类型任意,如“text/plain”、“application/xml”等都可以匹配。
6.5.4.5、请求头数据中指定参数名!=值
@RequestMapping(value="/header/test7", headers = "Accept!=text/vnd.wap.wml"):表示请求的URL必须为“/header/test7” 且 请求头中必须有“Accept”参数但值不等于“text/vnd.wap.wml”即可匹配。
6.5.4.6、组合使用是“且”的关系
@RequestMapping(value="/header/test8", headers = {"Accept!=text/vnd.wap.wml","abc=123"}):表示请求的URL必须为“/header/test8” 且 请求头中必须有“Accept”参数但值不等于“text/vnd.wap.wml”且 请求中必须有参数“abc=123”即可匹配。
注:Accept:text/html,application/xhtml+xml,application/q=0.9,*/*;q=0.8
如果您的请求中含有Accept:“*/*”,则可以匹配功能处理方法上的如“text/html”、“text/*”,“application/xml”等。
118 顶12 踩
浏览 75292
* 请求头数据中指定参数通配
*/ @RequestMapping(headers="tom=cat/*",value="/myHeader") public String headerValue(){
System.out.println("请求头数据中指定参数通配");
return "test"; }以上在Modify Header中输入& tom(第一个值)& cat/cat2(第二个值) 貌似不可以,但是如果输入&& tom&&& cat/*& 才能进入,tao 哥 解释一下?....抱歉,理会错了,原来headers的参数只能是Accept=cat/*....我理会错了
SpringMVC的源代码在哪下啊?噢,找到了,导航页没有提供链接啊。
jinnianshilongnian 写道yangfuchao418 写道能不能方法名自动映射成URL,不用再写什么注解配置了。只有需要其他名字的时候才加注解springmvc 的 coccoc还是需要 @RequestMapping 这种注解直接不使用注解的只有使用给你发的连接的那种方式
& 上一页 1
jinnianshilongnian
浏览量:1432290
浏览量:1714295
浏览量:3315728
浏览量:155316
浏览量:890826
浏览量:169967
浏览量:2416096
浏览量:326401
脚手架 es 编译好了,但是跑不起来啊tao哥,能不能修复一下 ...
呵呵6666 写道spring boot基础学习系列文章:ht ...
jing3232 写道请问,lua脚本接连mysql,用域名的 ...
期待大作~~

我要回帖

更多关于 springmvc 判断method 的文章

 

随机推荐