Spring Boot Web 请求处理

2022-11-26  本文已影响0人  Tinyspot

1. 前置

1.1 组合注解

1.2 RESTful 风格

@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser() {
    return "GET-success";
}

@RequestMapping(value = "/user", method = RequestMethod.POST)
public String saveUser() {
    return "POST-success";
}

html 的表单

<form action="/user" method="get">
    <input value="REST-GET" type="submit">
</form>
<form action="/user" method="post">
    <input value="REST-POST" type="submit">
</form>

1.3 核心 Filter - HiddenHttpMethodFilter

<form action="/user" method="delete">
    <input value="REST-DELETE" type="submit">
</form>

默认发送的是 GET 请求,若需发送 delete 请求

<form action="/user" method="post">
    <input name="_method" type="hidden" value="DELETE">
    <input value="REST-DELETE" type="submit">
</form>

application.yml 里的配置 spring.mvc.hiddenmethod.filter.enable=true

@RequestMapping(value = "/user", method = RequestMethod.DELETE)
public String delUser() {
    return "DELETE-success";
}

2. Rest 原理

2.1 HiddenHttpMethodFilter

表单无法发送 delete 和 put 请求
原因是 WebMvcAutoConfiguration 类里默认的 OrderedHiddenHttpMethodFilter

public class WebMvcAutoConfiguration {
  @Bean
  @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
  @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled")
  public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
    return new OrderedHiddenHttpMethodFilter();
  }
}
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    public static final String DEFAULT_METHOD_PARAM = "_method";
    
    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);
            // ....
        }
        filterChain.doFilter(requestToUse, response);
    }
}

2.2 改变默认的 _method

@Configuration
public class WebConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
        methodFilter.setMethodParam("_form");
        return methodFilter;
    }
}

3. 请求映射原理

3.1 @RequestMapping

@RestController
@RequestMapping("/web")
public class HelloController {
  // @RequestMapping(value = "/user", method = RequestMethod.GET)
  @GetMapping("/user")
  public String getUser() {
    return "GET-success";
  }
}

3.2 请求映射原理

image.png image.png
public class DispatcherServlet extends FrameworkServlet {
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // ...
        mappedHandler = getHandler(processedRequest);
    }
}
上一篇下一篇

猜你喜欢

热点阅读