Spring MVC 概念模型 : 接口 RequestCondition

源代码版本 : spring-webmvc-5.1.4.RELEASE

概述

接口RequestConditionSpring MVC对一个请求匹配条件的概念建模。最终的实现类可能是针对以下情况之一:路径匹配,头部匹配,请求参数匹配,可产生MIME匹配,可消费MIME匹配,请求方法匹配,或者是以上各种情况的匹配条件的一个组合。

源代码分析

RequestCondition接口定义

package org.springframework.web.servlet.mvc.condition;

import javax.servlet.http.HttpServletRequest;

import org.springframework.lang.Nullable;

public interface RequestCondition<T> {

	// 和另外一个请求匹配条件合并,具体合并逻辑由实现类提供
	T combine(T other);

	// 检查当前请求匹配条件和指定请求request是否匹配,如果不匹配返回null,
	// 如果匹配,生成一个新的请求匹配条件,该新的请求匹配条件是当前请求匹配条件
	// 针对指定请求request的剪裁。
	// 举个例子来讲,如果当前请求匹配条件是一个路径匹配条件,包含多个路径匹配模板,
	// 并且其中有些模板和指定请求request匹配,那么返回的新建的请求匹配条件将仅仅
	// 包含和指定请求request匹配的那些路径模板。
	@Nullable
	T getMatchingCondition(HttpServletRequest request);

	// 针对指定的请求对象request比较两个请求匹配条件。
	// 该方法假定被比较的两个请求匹配条件都是针对该请求对象request调用了
	// #getMatchingCondition方法得到的,这样才能确保对它们的比较
	// 是针对同一个请求对象request,这样的比较才有意义(最终用来确定谁是
	// 更匹配的条件)。
	int compareTo(T other, HttpServletRequest request);

}

由接口源代码可以看出,接口RequestCondition是一个泛型接口。事实上,它的泛型参数T通常也会是一个RequestCondition对象。

抽象基类实现AbstractRequestCondition

框架对接口RequestCondition有一组具体实现类。对这些具体实现类的一些通用逻辑,比如equals,hashCodetoString,是被放到抽象基类AbstractRequestCondition来实现的。同时AbstractRequestCondition还通过protected抽象方法约定了实现类其他的一些内部通用逻辑,具体如下所示:

package org.springframework.web.servlet.mvc.condition;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.lang.Nullable;

/**
 * @param <T> the type of objects that this RequestCondition can be combined
 * with and compared to
 */
public abstract class AbstractRequestCondition<T extends AbstractRequestCondition<T>> implements RequestCondition<T> {

	/**
	 * 当前请求匹配条件对象是否内容为空
	 * @return  true if empty; false otherwise
	 */
	public boolean isEmpty() {
		return getContent().isEmpty();
	}

	/**
	 * 一个请求匹配条件可能由多个部分组成,这些组成部分被包装成一个名为 content 的集合
	 * 比如 :
	 * 对于请求路径匹配条件,可能有多个 URL pattern,
	 * 对于请求方法匹配条件,可能有多个 HTTP request method,
	 * 对于请求参数匹配条件,可能有多个 param 表达式 .
	 * @return a collection of objects, never  null , 可能为空集合
	 */
	protected abstract Collection<?> getContent();

	/**
	 * The notation to use when printing discrete items of content.
	 * 将该条件作为字符串展示时,各个组成部分之间的中缀标识符。比如 "||" 或者 "&&" 等。
	 * For example {@code " || " for URL patterns or {@code " && "} for param expressions.
	 */
	protected abstract String getToStringInfix();


	// equlas 实现 
	@Override
	public boolean equals(@Nullable Object other) {
		if (this == other) {
			return true;
		}
		if (other == null || getClass() != other.getClass()) {
			return false;
		}
		return getContent().equals(((AbstractRequestCondition<?>) other).getContent());
	}

	// hashCode 实现
	@Override
	public int hashCode() {
		return getContent().hashCode();
	}

	// toString 实现
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder("[");
		for (Iterator<?> iterator = getContent().iterator(); iterator.hasNext();) {
			Object expression = iterator.next();
			builder.append(expression.toString());
			if (iterator.hasNext()) {
				builder.append(getToStringInfix());
			}
		}
		builder.append("]");
		return builder.toString();
	}

}

针对某种请求匹配条件具体实现类

实现类简介
PatternsRequestCondition路径匹配条件
RequestMethodsRequestCondition请求方法匹配条件
ParamsRequestCondition请求参数匹配条件
HeadersRequestCondition头部信息匹配条件
ConsumesRequestCondition可消费MIME匹配条件
ProducesRequestCondition可生成MIME匹配条件

该表格提到的RequestCondition具体实现类都继承自AbstractRequestCondition抽象基类,都是针对请求匹配的某一个方面:请求路径,请求头部,请求方法,请求参数,可消费MIME,可生成MIME等等。

另外框架还提供了一个实现类RequestConditionHolder,这是一个匹配条件持有器,用于持有某个RequestCondition对象。如果你想持有一个RequestCondition对象,但其类型事先不可知,那么这种情况下该工具很有用。但要注意的是如果要合并或者比较两个RequestConditionHolder对象,也就是二者所持有的RequestCondition对象,那么二者所持有的RequestCondition对象必须是类型相同的,否则会抛出异常ClassCastException

实际上,以上面的这些实现类为基础, Spring MVC有另外一个RequestCondition实现类RequestMappingInfo,该实现类不是针对请求匹配某个一方面的实现类,而是包含了一个请求匹配的所有方面。我们会在另外一篇文章中作介绍。

参考文章

Spring MVC 概念模型 : 注解 @RequestMapping 信息载体 RequestMappingInfo
Spring MVC HandlerMapping : RequestMappingHandlerMapping 源代码解析

————————————————
版权声明:本文为CSDN博主「安迪源文」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/andy_zhang2007/article/details/88913776

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值