@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = “spring.mvc.hiddenmethod.filter”, name = “enabled”, matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
通过OrderedHiddenHttpMethodFilter进入父类HiddenHttpMethodFilter:
在使用之前,我们需要将后两个的请求方式改写成post方式,并且需要在请求的时候传入一个_method
方法(设置隐藏域);
<input value="REST-PUT提交"type=“submit” />
为什么要这样设置呢?我们到HiddenHttpMethodFilter中看下。
流程:
-
第一步保存了传入的请求
-
当该请求时post,并且请求没有异常,才能进入下面方法,不是Post请求将直接通过过滤器链放行。
-
获取请求中的参数(this.methodParam)
-
DEFAULT_METHOD_PARAM = _method获得(作为真正的请求方式)
然后再测试,发现还是没有实现。
我再回到WebMvcConfiguration中:
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = “spring.mvc.hiddenmethod.filter”, name = “enabled”, matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
首先该类存在于容器中。
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
当容器中不存在HiddenHttpMethodFilter
这个类的时候,下面内容开启(条件装配);
@ConditionalOnProperty(prefix = “spring.mvc.hiddenmethod.filter”, name = “enabled”, matchIfMissing = false)
表示:绑定的配置文件中:spring.mvc.hiddenmethod.filter
名字为enable是默认不开启的(后续版本可能开启)。这样我们就找到了问题的所在。
所以我们需要在配置文件中配置(两种方法都可以)。
yaml:
spring:
mvc:
hiddenmethod:
filter:
enabled: true
properties:
spring.mvc.hiddenmethod.filter.enabled=true
重启项目:成功解决。
源码分析:
主要是分析doFilterInternal:
@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);
}
-
表单提交会带上**_method=PUT**
-
请求过来被HiddenHttpMethodFilter拦截
-
请求是否正常,并且是POST
-
获取到**_method**的值。
-
兼容以下请求;PUT.DELETE.PATCH
当方法走到上述代码11行时,进入ALLOWED_METHODS:
private static final List ALLOWED_METHODS =
Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
如果请求里的参数在ALLOWED_METHODS存在,则执行下面代码。
- 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
进入HttpMethodRequestWrapper对象中,向上找父类。本质还是HttpServletRequest
由下面代码:
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() {
return this.method;
}
}
可知,接收到前面的请求封装为HttpMethodRequestWrapper返回。
最后
既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?
就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。
如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!
且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:
-
出神入化——SpringCloudAlibaba.pdf
-
SpringCloud微服务架构笔记(一).pdf
-
SpringCloud微服务架构笔记(二).pdf
-
SpringCloud微服务架构笔记(三).pdf
-
SpringCloud微服务架构笔记(四).pdf
-
Dubbo框架RPC实现原理.pdf
-
Dubbo最新全面深度解读.pdf
-
Spring Boot学习教程.pdf
-
SpringBoo核心宝典.pdf
-
第一本Docker书-完整版.pdf
-
使用SpringCloud和Docker实战微服务.pdf
-
K8S(kubernetes)学习指南.pdf
另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!
构笔记(四).pdf
-
Dubbo框架RPC实现原理.pdf
-
Dubbo最新全面深度解读.pdf
-
Spring Boot学习教程.pdf
-
SpringBoo核心宝典.pdf
-
第一本Docker书-完整版.pdf
-
使用SpringCloud和Docker实战微服务.pdf
-
K8S(kubernetes)学习指南.pdf
[外链图片转存中…(img-3rha86kG-1714452751357)]
另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!
[外链图片转存中…(img-uvIRIJY0-1714452751357)]