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。

 

posted @ 2021-06-28 20:15  YuyuFishSmile  阅读(240)  评论(0)    收藏  举报