Learn from:尚硅谷
Rest请求的使用 访问方法的改变原来的访问都是将get、post、delete、put分开写的,Rest请求将其进行了一定的合并。
以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
现在: /user -> (GET DELETE PUT POST)
核心的Filter:OrderedHiddenHttpMethodFilter.class
需要配置的属性spring.mvc.hiddenmethod.filter=true
修改后的表单,我们在表单里面添加了一行input,但是这个input我们写了一个name,和他的值,然后我们将他隐藏。
html代码:
Title
我们的Controller这样写:
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser(){
return "GET-张三";
}
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String postUser(){
return "POST-张三";
}
@RequestMapping(value = "/user", method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}
@RequestMapping(value = "/user", method = RequestMethod.PUT)
public String putUser(){
return "PUT-张三";
}
这样配置就是正确的,但是我们发现点击下面两个还是会返回post请求。
我们可以去WebMvcAutoConfiguration.class里面查看一下。
找到OrderedHiddenHttpMethodFilter这个过滤器。
这个过滤器就是拦截了我们的http请求,并且我们看到只有当spring.mvc.hiddenmethod.filter这个属性为enabled的时候,才会启用这个Filter。
我们去yaml里面配置一下这个属性:
spring:
mvc:
hiddenmethod:
filter:
enabled: true #开启页面表单的Rest功能
这样我们就可以的delete请求和put请求就可以生效了。
Rest请求的原理我们知道Rest请求的核心为Filter:OrderedHiddenHttpMethodFilter.class
因此我们去这个类里面去看一下到底是什么原因。
我们发现这个类是继承了另一个HiddenHttpMethodFilter.class
我们点进去看,会发现一个新的方法doFilterInternal()
我们可以看只有当方法为POST、且没有什么报错的时候才会进去这个Filter,然后获取name为this.methodParam的param。且这个name就为我们之前html设置的一样。
这也就是为什么我们表单的method为POST的原因。
我们首先打开之前的表单页面,然后再给这个方法打个断点运行。
在网页中点击delete方法,我们在代码中计算一下,发现为Post请求。
往下走,我们会发现这个paramValue的值为delete,也就是我们html表单里面设置的值。
我们看到后面还会将这个值设置为大写的形式,因此在form表单里面设置的值大小写都行。
然后判断我们的请求是否存在于我们的列表中,存在我们就对requests进行包装。
我们可以看到requestsWrapper继承了HttpServletRequestWrapper,而这个类又继承了httpServletRequest,也就是原生的request接口,所以这个Wrapper也是一个Request接口。意思就是将我们的method包装进去了。
我们知道这个RequestWrapper写了一个getMethod方法,并且将我们自定义的method的值返回。
那么以后再调用Request的method就是我们自己定义的method的值了。
我们还可以看到不仅仅支持put和delete,还支持patch
我们也可以自己定义Filter。
我们自己创建一个HiddenHttpMethodFilter,然后调用它的setMethodParam("_m")方法修改MethodParam的值就可以了。
不要忘记@Bean
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}
请求的新注解
直接@{methodname}+Mapping



