1、我們知道表單送出,隻能是get請求或者post請求。但是restful風格要求有:
get 查詢
post 插入
delete 删除
put 更新
4種請求方式。那麼springboot是怎麼支援表單送出的restful風格的呢?
解決:通過隐藏請求參數完成
用法:
- 核心Filter;HiddenHttpMethodFilter
- 用法: 表單method=post,隐藏域 _method=put
- SpringBoot中手動開啟
- 擴充:如何把_method 這個名字換成我們自己喜歡的。
原理:
- 表單送出會帶上_method=PUT
- 請求過來被HiddenHttpMethodFilter攔截
- 請求是否正常,并且是POST
- 擷取到_method的值。
- 相容以下請求;PUT.DELETE.PATCH
- 原生request(post),包裝模式requesWrapper重寫了getMethod方法,傳回的是傳入的值。
- 過濾器鍊放行的時候用wrapper。以後的方法調用getMethod是調用requesWrapper的。
自動配置類配置filter:
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
方法參數的關鍵代碼
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter(requestToUse, response);
}
自定義參數名稱:
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}