SpringBoot_04使用Rest风格源码分析

Rest风格请求处理

	@Bean
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	//判断有没有这个类,是不是开启的,如果没有的话,默认就是关闭的
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
		return new OrderedHiddenHttpMethodFilter();
	}
spring:
   web:
    hiddenmethod:
      filter:
        enabled: true   #添加hidden,进行开启
	@Override
   protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
   		throws ServletException, IOException {

   	HttpServletRequest requestToUse = request;
   	//判断是否是POST请求
   	if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
   		//获取页面name为_methodParam的值
   		String paramValue = request.getParameter(this.methodParam);
   		if (StringUtils.hasLength(paramValue)) {
   		//转换为大写
   			String method = paramValue.toUpperCase(Locale.ENGLISH);
   			if (ALLOWED_METHODS.contains(method)) {
   			//进行包装,替换我们原生的request为requestToUse(主要是为了将method替换为传的值)
   				requestToUse = new HttpMethodRequestWrapper(request, method);
   			}
   		}
   	}

   	filterChain.doFilter(requestToUse, response);
   }

请求源码分析

每个请求最终都会执行我们的doDispatch方法
在这里插入图片描述

分析如下:
1.

// 确定方法的请求,是由哪一个控制器来完成的,接下来看看是如何实现的吧
mappedHandler = getHandler(processedRequest);

1.1

	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
	   		//循环遍历handlerMapings判断一下我们使用哪一个handlerMapping
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

1.2所有的hanlerMapping: (像一个大的map一样会存放我们所有的路径)
在这里插入图片描述

源码分析:

@Nullable
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<>();
		//	根据我们的路径寻找到匹配的
		List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
		if (directPathMatches != null) {
		//再根据我们的请求进行匹配
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
		}
		if (!matches.isEmpty()) {
		// 取出来第一个,  判断我们是否有多个,有多个的话,就报异常
			Match bestMatch = matches.get(0);
			if (matches.size() > 1) {
				Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
				matches.sort(comparator);
				bestMatch = matches.get(0);
				if (logger.isTraceEnabled()) {
					logger.trace(matches.size() + " matching mappings: " + matches);
				}
				if (CorsUtils.isPreFlightRequest(request)) {
					for (Match match : matches) {
						if (match.hasCorsConfig()) {
							return PREFLIGHT_AMBIGUOUS_MATCH;
						}
					}
				}
				else {
					Match secondBestMatch = matches.get(1);
					if (comparator.compare(bestMatch, secondBestMatch) == 0) {
						Method m1 = bestMatch.getHandlerMethod().getMethod();
						Method m2 = secondBestMatch.getHandlerMethod().getMethod();
						String uri = request.getRequestURI();
						throw new IllegalStateException(
								"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
					}
				}
			}
			request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.getHandlerMethod();
		}
		else {
			return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值