1. 程式人生 > 其它 >Spring Boot 學習(一) Rest對映

Spring Boot 學習(一) Rest對映

再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)

  1. 表單提交會帶上 _method = PUT
  2. 請求過來會被filter攔截(OrderedHiddenHttpMethodFilter ),①先判斷請求是否正常,②之後再判斷是否是post方式,之後獲取到_method的值(表單裡帶入的value裡的值)
  3. 原生的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。