springboot加载rest风格的源码

17 篇文章 0 订阅
5 篇文章 0 订阅

1.开启页面表单的Rest功能

spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true   #开启页面表单的Rest功能

2.rest风格支持

rest风格支持(使用HTTP请求方式动词来表示对资源的操作)

  • 以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
  • 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户

核心Filter : HiddenHttpMethodFilter

3.springboot加载rest风格的源码

rest风格_拦截器拦截“_method”

public class HiddenHttpMethodFilter extends OncePerRequestFilter {

	private static final List<String> ALLOWED_METHODS =
			Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
					HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));

	/** 默认方法参数: {@code _method}. */
	public static final String DEFAULT_METHOD_PARAM = "_method";

	private String methodParam = DEFAULT_METHOD_PARAM;


	/**
	 * 设置参数名称以查找HTTP方法。
	 * @see #DEFAULT_METHOD_PARAM
	 */
	public void setMethodParam(String methodParam) {
		Assert.hasText(methodParam, "'methodParam' must not be empty");
		this.methodParam = methodParam;
	}

	@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);
				//	private static final List<String> ALLOWED_METHODS =
			//Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
					//HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
					//可以看到支持DELETE,PUT,PATCH
				if (ALLOWED_METHODS.contains(method)) {
					requestToUse = new HttpMethodRequestWrapper(request, method);
				}
			}
		}

		filterChain.doFilter(requestToUse, response);
	}


	/**
	 * Simple {@link HttpServletRequest} wrapper that returns the supplied method for
	 * {@link HttpServletRequest#getMethod()}.
	 * 包装模式的`HttpMethodRequestWrapper`重写了getMethod方法,返回传入的值
	 */
	private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {

		private final String method;

		public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
			super(request);
			this.method = method;
		}
		//包装模式的`HttpMethodRequestWrapper`重写了getMethod方法,返回传入的值
		@Override
		public String getMethod() {
			return this.method;
		}
	}

}

  • 自动转为大写,大小写忽略
  • 可以看到支持DELETE,PUT,PATCH
  • 包装模式的HttpMethodRequestWrapper重写了getMethod方法,返回传入的值
  • 必须是原生的servlet请求才会拦截,如PostMan直接发送Put、delete等方式请求,无需Filter转换。
  • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。

4.注解

  • @PutMapping
  • @DeleteMapping
  • @GetMapping
  • @PostMapping

5.自定义_method 这个名字。

5.1 如果spring容器中没有HiddenHttpMethodFilter则执行以下代码

那么我们可以自己写一个放进去

	@Bean
	//如果spring容器中没有HiddenHttpMethodFilter则执行以下代码
	//那么我们可以自己写一个放进去
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
		return new OrderedHiddenHttpMethodFilter();
	

5.2找到原生HiddenHttpMethodFilter类分析

改变默认的“_Method”方式

5.3 写HiddenHttpMethodFilter类放入spring容器

package com.fww.demo.controller;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;

/**
 * @author dongtangqiang
 */
@Configuration(proxyBeanMethods = false)
public class WebConfig {
    
    @Bean
    public HiddenHttpMethodFilter HiddenHttpMethodFilter(){
        HiddenHttpMethodFilter MethodFilter = new HiddenHttpMethodFilter();
        MethodFilter.setMethodParam("_m");
        return MethodFilter;
    }
    
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值