在WebMvcAutoConfiguration自动配置类中有一个hiddenHttpMethodFilter方法
@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
@ConditionalOnProperty(
prefix = "spring.mvc.hiddenmethod.filter",
name = {"enabled"}
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
看它的底层doFilterInternal方法(在OrderedHiddenHttpMethodFilter类继承的HiddenHttpMethodFilter类中)
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter((ServletRequest)requestToUse, response);
}
处理表单请求
在表单请求中我们只能执行post和get请求,那么我们如何执行delete和put请求呢?我们看代码,
if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null)
//如果为post请求并且没有错误时
String paramValue = request.getParameter(this.methodParam);
//拿到请求中“_method”属性。this.methodParam="_method"
if (StringUtils.hasLength(paramValue))
//如果有值
String method = paramValue.toUpperCase(Locale.ENGLISH) //转为大写
if (ALLOWED_METHODS.contains(method))
//如果ALLOWED_METHODS包含了这个方法
//ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));包含了put、delete、patch方法
requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
//把请求变为一个包装类,重写了HttpServletRequest的getMethod方法。使用了包装模式
filterChain.doFilter((ServletRequest)requestToUse, response);
//最后放行
实例是这么写的,默认隐藏所以type是hidden,上边方式我们要写post
还要看条件配置,所以我们要配置开启。
@ConditionalOnProperty(
prefix = "spring.mvc.hiddenmethod.filter",
name = {"enabled"}
)
spring.mvc.hiddenmethod.filter.enabled=true
处理客户端请求如postman的请求
我们在http层就已经改为我们自己的提交方式,所以就不会走它了(除非你是post方式)
if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null)