- 查看WebMvcAutoConfiguration,默认配置了OrderedHiddenHttpMethodFilter
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = { "/" };
@Bean
// 如果没有自定义的组件,则使用默认的组件
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
// 表示该配置需要开启,才能使用rest风格的请求
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
- 查看OrderedHiddenHttpMethodFilter
public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements OrderedFilter {
public static final int DEFAULT_ORDER = -10000;
private int order = -10000;
public OrderedHiddenHttpMethodFilter() {
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
}
- 查看HiddenHttpMethodFilter,表示我们需要带1个隐藏的参数项_method
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
private static final List<String> ALLOWED_METHODS;
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = "_method";
public HiddenHttpMethodFilter() {
}
public void setMethodParam(String methodParam) {
Assert.hasText(methodParam, "'methodParam' must not be empty");
this.methodParam = methodParam;
}
- Rest原理(表单提交要使用REST的时候)
● 表单提交会带上_method=PUT
● 请求过来被HiddenHttpMethodFilter拦截
○ 请求是否正常,并且是POST
■ 获取到_method的值。
■ 兼容以下请求;PUT.DELETE.PATCH
■ 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
■ 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。
- 测试
# 前端
测试REST风格;
<form action="/user" method="get">
<input value="REST-GET 提交" type="submit"/>
</form>
<form action="/user" method="post">
<input value="REST-POST 提交" type="submit"/>
</form>
<form action="/user" method="post">
<input name="_method" type="hidden" value="delete"/>
<input value="REST-DELETE 提交" type="submit"/>
</form>
<form action="/user" method="post">
<input name="_method" type="hidden" value="PUT"/>
<input value="REST-PUT 提交" type="submit"/>
</form>
# 后端
@RestController
public class HelloController {
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
return "GET-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
return "POST-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
return "PUT-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}
}
# yml
spring:
mvc:
hiddenmethod:
filter:
enabled: true #开启页面表单的Rest功能
- 其他写法
@RestController
public class HelloController {
@GetMapping("/user")
public String getUser(){
return "GET-张三";
}
@PostMapping("/user")
public String saveUser(){
return "POST-张三";
}
@PutMapping("/user")
public String putUser(){
return "PUT-张三";
}
@DeleteMapping("/user")
public String deleteUser(){
return "DELETE-张三";
}
}
- 自定义filter:作用是将_mothod改为自定义字符
# 后端webConfig中配置:
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}
# 前端表单中:
<form action="/user" method="post">
<input name="_m" type="hidden" value="delete"/>
<input value="REST-DELETE 提交" type="submit"/>
</form>
# 手动开启HiddenHttpMethodFilter,yml中配置
# 后端控制器:
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}