Spring Boot 學習(一) Rest對映
阿新 • • 發佈:2021-06-28
再controller中編寫同一個mapping的方法,但是對應的請求方式不同
package com.sp.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello.html") public String hello() { return "aaaa"; } @RequestMapping(value = "/user", method = RequestMethod.GET) public String getUser1() { return "GET"; } @RequestMapping(value = "/user", method = RequestMethod.POST) public String getUser2() { return"POST"; } @RequestMapping(value = "/user", method = RequestMethod.PUT) public String getUser3() { return "PUT"; } @RequestMapping(value = "/user", method = RequestMethod.DELETE) public String getUser4() { return "DELETE"; } }
在index.html中編寫from表單,傳送請求,跳轉頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Welcome Spring Boot Index</h1> <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="put"> <input value="REST-PUT" type="submit"> </form> <form action="/user" method="delete"> <input value="REST-DELETE" type="submit"> </form> </body> </html>
在這裡可以發現處理的請求只能是get和post,put和delete預設也顯示為get請求
同樣處理user請求,根據請求方式的不同可以實現不同的事務
在springboot中想要提交delete請求,表單需要把請求方式改為post,需要給表單上提交一個
<input name="_method" type="hidden" value="DELETE">
@Bean @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled") public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { return new OrderedHiddenHttpMethodFilter(); }
這裡通過檢視springboot原始碼發現,預設情況下spring.mvc.hiddenmethod.filter裡的enabled 為false,這裡需要在yaml中進行配置
spring:
mvc:
hiddenmethod:
filter:
enabled: true 開啟頁面表單的Rest功能
這時再去檢視PUT 和 DELETE請求,發現成功
這裡是基於表單使用Rest原理 (表單提交)(表單只能寫get 和post)
- 表單提交會帶上 _method = PUT
- 請求過來會被filter攔截(OrderedHiddenHttpMethodFilter ),①先判斷請求是否正常,②之後再判斷是否是post方式,之後獲取到_method的值(表單裡帶入的value裡的值)
- 原生的request(post),包裝模式HttpMethodRequestWrapper 重寫了getMethod方法,返回的是傳入的值
在HiddenHttpMethodFilter類中編寫了,獲取原生請求,如何判斷原生請求是否為post
@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); }
request.getParameter(this.methodParam); 獲取請求引數
之後檢視methodParam 可以發現有_method ,通過獲取_method引數
private static final List<String> ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name())); /** Default method parameter: {@code _method}. */ public static final String DEFAULT_METHOD_PARAM = "_method"; private String methodParam = DEFAULT_METHOD_PARAM;
通過獲取到的_method裡的value值,再判斷是否是允許的請求方式
有put、delete、patch的請求方式
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper { private final String method; public HttpMethodRequestWrapper(HttpServletRequest request, String method) { super(request); this.method = method; } @Override public String getMethod() { //對原生的getMethod進行重寫
return this.method; } }
Rest使用客戶端工具,
如PostMan直接傳送PUT、DELETE等請求的時候,就無需Fillter。