accept包

RequestedContentTypeResolver

处理mediaType的接口。

public interface RequestedContentTypeResolver {List<MediaType> MEDIA_TYPE_ALL_LIST = Collections.singletonList(MediaType.ALL);/**将给定的请求解析为请求的媒体类型列表。返回的列表首先按特异性排序,然后按质量参数排序。*/List<MediaType> resolveMediaTypes(ServerWebExchange exchange);}

FixedContentTypeResolver

解析器始终解析为固定列表的MediaType。这可以用作“最后一行”策略,当客户端没有请求任何媒体类型时提供解析。

public class FixedContentTypeResolver implements RequestedContentTypeResolver {private final List<MediaType> contentTypes;
}

HeaderContentTypeResolver

根据请求的“Accept” header 解析。

public class HeaderContentTypeResolver implements RequestedContentTypeResolver {@Overridepublic List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {try {//Accept header。List<MediaType> mediaTypes = exchange.getRequest().getHeaders().getAccept();MediaType.sortBySpecificityAndQuality(mediaTypes);return (!CollectionUtils.isEmpty(mediaTypes) ? mediaTypes : MEDIA_TYPE_ALL_LIST);}catch (InvalidMediaTypeException ex) {String value = exchange.getRequest().getHeaders().getFirst("Accept");throw new NotAcceptableStatusException("Could not parse 'Accept' header [" + value + "]: " + ex.getMessage());}}}

ParameterContentTypeResolver

根据查询参数解析MediaType。参数自定义。

public class ParameterContentTypeResolver implements RequestedContentTypeResolver {/** Primary lookup for media types by key (e.g. "json" -> "application/json") */private final Map<String, MediaType> mediaTypes = new ConcurrentHashMap<>(64);private String parameterName = "format";@Overridepublic List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {String key = exchange.getRequest().getQueryParams().getFirst(getParameterName());if (!StringUtils.hasText(key)) {return MEDIA_TYPE_ALL_LIST;}//通过map 查找对应MediaTypekey = formatKey(key);MediaType match = this.mediaTypes.get(key);if (match == null) {match = MediaTypeFactory.getMediaType("filename." + key).orElseThrow(() -> {List<MediaType> supported = new ArrayList<>(this.mediaTypes.values());return new NotAcceptableStatusException(supported);});}this.mediaTypes.putIfAbsent(key, match);return Collections.singletonList(match);}}

result包

HandlerResultHandlerSupport

HandlerResultHandler的基类,支持内容协商和访问ReactiveAdapter注册表。

public abstract class HandlerResultHandlerSupport implements Ordered {private static final List<MediaType> ALL_APPLICATION_MEDIA_TYPES =Arrays.asList(MediaType.ALL, new MediaType("application"));private final RequestedContentTypeResolver contentTypeResolver;private final ReactiveAdapterRegistry adapterRegistry;private int order = LOWEST_PRECEDENCE;/** 获取最合适的mediaType*/@Nullableprotected MediaType selectMediaType(ServerWebExchange exchange, Supplier<List<MediaType>> producibleTypesSupplier) {//如果header中有contentType,直接返回。MediaType contentType = exchange.getResponse().getHeaders().getContentType();if (contentType != null && contentType.isConcrete()) {if (logger.isDebugEnabled()) {logger.debug(exchange.getLogPrefix() + "Found 'Content-Type:" + contentType + "' in response");}return contentType;}//查找合适的MediatypeList<MediaType> acceptableTypes = getAcceptableTypes(exchange);List<MediaType> producibleTypes = getProducibleTypes(exchange, producibleTypesSupplier);Set<MediaType> compatibleMediaTypes = new LinkedHashSet<>();for (MediaType acceptable : acceptableTypes) {for (MediaType producible : producibleTypes) {if (acceptable.isCompatibleWith(producible)) {compatibleMediaTypes.add(selectMoreSpecificMediaType(acceptable, producible));}}}List<MediaType> result = new ArrayList<>(compatibleMediaTypes);MediaType.sortBySpecificityAndQuality(result);MediaType selected = null;for (MediaType mediaType : result) {if (mediaType.isConcrete()) {selected = mediaType;break;}else if (mediaType.isPresentIn(ALL_APPLICATION_MEDIA_TYPES)) {selected = MediaType.APPLICATION_OCTET_STREAM;break;}}if (selected != null) {selected = selected.removeQualityValue();... LOG ....}else if (logger.isDebugEnabled()) {... LOG ... }return selected;}}    

View包

View

View接口用于渲染HandlerResult。视图通常是通过名称来选择的,并使用ViewResolver来解析,例如将其与HTML模板匹配。此外,视图可以基于模型中包含的多个属性呈现。视图还可以选择从模型中选择一个属性,使用任何现有的编码器来呈现替代媒体类型。

public interface View {String BINDING_CONTEXT_ATTRIBUTE = View.class.getName() + ".bindingContext";/*** Return the list of media types this View supports, or an empty list.*/default List<MediaType> getSupportedMediaTypes() {return Collections.emptyList();}/*** Whether this View does rendering by performing a redirect.*/default boolean isRedirectView() {return false;}/** 渲染 HandlerResult*/Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, ServerWebExchange exchange);}

Diagram

AbstractView

ublic abstract class AbstractView implements View, BeanNameAware, ApplicationContextAware {/** Well-known name for the RequestDataValueProcessor in the bean factory. */public static final String REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME = "requestDataValueProcessor";protected final Log logger = LogFactory.getLog(getClass());private final ReactiveAdapterRegistry adapterRegistry;private final List<MediaType> mediaTypes = new ArrayList<>(4);private Charset defaultCharset = StandardCharsets.UTF_8;@Nullableprivate String requestContextAttribute;@Nullableprivate String beanName;@Nullableprivate ApplicationContext applicationContext;/**渲染Model*/@Overridepublic Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType,ServerWebExchange exchange) {... ... //设置contentTypeif (contentType != null) {exchange.getResponse().getHeaders().setContentType(contentType);}return getModelAttributes(model, exchange).flatMap(mergedModel -> {// Expose RequestContext?if (this.requestContextAttribute != null) {mergedModel.put(this.requestContextAttribute, createRequestContext(exchange, mergedModel));}//渲染modelreturn renderInternal(mergedModel, contentType, exchange);});}}

AbstractUrlBasedView

基于Url的视图渲染

public abstract class AbstractUrlBasedView extends AbstractView implements InitializingBean {@Nullableprivate String url;
}   

RedirectView

重定向到一个Url。

ScriptTemplateView

解释性模板视图。

FreeMarkerView

FreeMarker视图

ViewResolver

ViewResolver通过name解析成View。

public interface ViewResolver {Mono<View> resolveViewName(String viewName, Locale locale);
}

Diagram

Rendering

/**Public API for HTML rendering
*/
public interface Rendering {Object view();/*** Return attributes to add to the model.*/Map<String, Object> modelAttributes();/*** Return the HTTP status to set the response to.*/@NullableHttpStatus status();/*** Return headers to add to the response.*/HttpHeaders headers();
}

condition包

RequestCondition

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

public interface RequestCondition<T> {T combine(T other);@NullableT getMatchingCondition(ServerWebExchange exchange);int compareTo(T other, ServerWebExchange exchange);}

method包

类似Mvc,用于处理 Method类型的handler。

function包

一些常用的函数式接口及实现。

socket包

反应式WebSocket交互的抽象和支持类。

WebSocketHandler

public interface WebSocketHandler {default List<String> getSubProtocols() {return Collections.emptyList();}Mono<Void> handle(WebSocketSession session);
}

webflux系列--源码解析二相关推荐

  1. 【深度学习模型】智云视图中文车牌识别源码解析(二)

    [深度学习模型]智云视图中文车牌识别源码解析(二) 感受 HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等. 代码不可谓不混乱(别忘了这是职业公司的准产品级代码 ...

  2. rock带你读CornerNet-lite系列源码(二)

    文章目录 前言 CorNerNet 结构 CornerNet_saccade结构 attention机制 CornerNet_Squeeze结构 构建Groundtruth 热图 focal loss ...

  3. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

  4. Kubernetes学习笔记之Calico CNI Plugin源码解析(二)

    女主宣言 今天小编继续为大家分享Kubernetes Calico CNI Plugin学习笔记,希望能对大家有所帮助. PS:丰富的一线技术.多元化的表现形式,尽在"360云计算" ...

  5. Mobx 源码解析 二(autorun)

    前言 我们在Mobx 源码解析 一(observable)已经知道了observable 做的事情了, 但是我们的还是没有讲解明白在我们的Demo中,我们在Button 的Click 事件中只是对ba ...

  6. android网络框架retrofit源码解析二

    注:源码解析文章参考了该博客:http://www.2cto.com/kf/201405/305248.html 前一篇文章讲解了retrofit的annotation,既然定义了,那么就应该有解析的 ...

  7. Thrift源码解析(二)序列化协议

    概述 对于一个RPC框架,定义好网络数据的序列化协议是最基本的工作,thrift的序列化协议主要包含如下几种: TBinaryProtocol TCompactProtocol TJSONProtoc ...

  8. Spring Cloud微服务系列-Eureka Client源码解析(二)

    导语   上一篇博客中介绍了关于Eureka Client源码的基础部分,如果对于基础部分不是很了解的读者可以点击下面的连接进入到源码分析一中,从头开始学习 Spring Cloud微服务系列 Dis ...

  9. matlabeig函数根据什么原理_vue3.0 源码解析二 :响应式原理(下)

    一 回顾上文 上节我们讲了数据绑定proxy原理,vue3.0用到的基本的拦截器,以及reactive入口等等.调用reactive建立响应式,首先通过判断数据类型来确定使用的hander,然后创建p ...

最新文章

  1. ATL服务器:用 Visual C++创建的高性能的Web应用程序和XML Web 服务
  2. 已婚男人看见美女都这个眼神?
  3. lr_start_timer,lr_get_transaction_duration,lr_get_transaction_wasted_time函数使用总结
  4. 计算机语言学 自然语言处理程序,利用知网进行(计算机)自然语言处理
  5. EMS1.0.0项目的敏捷实践
  6. Counter 用法 from collections import Counter
  7. 怎么理解汉罗塔问题_小白理解的汉诺塔中的递归问题
  8. Google 高薪争夺 Rust 人才,将用 Rust 重构关键组件!
  9. 数据可视化(5)--jqplot经典实例
  10. 负载均衡和故障转移的使用案例
  11. mfc 制作不同的文档模板mdi不同的子窗体_法律行业python教程——利用python批量制作律师函...
  12. 怎么把文件传到虚拟机里
  13. 2022前端春招——CVTE笔试编程题
  14. C++ STL 思维导图,脑图,树形图。
  15. 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界:光照与材质专场
  16. 机器人 陆梅东_第十八届全国中小学组电脑制作活动上海赛区.DOC
  17. 三相电检测电路c语言,三相缺相检测电路的原理分析
  18. x的y次方python表达式怎么写_x 的 y 次方(xy) 以下表达式正确的是________
  19. opencv(c++)几何变换------图像平移、旋转、缩放、翻转、剪贴
  20. 参考文档一:性能测试---测试方案

热门文章

  1. 通向架构师的道路(第十天)之Axis2 Web Service(一)
  2. 【Hibernate】JDBC操作与hibernate的区别
  3. XorPay.com 支付平台介绍【支持个人申请】
  4. re:Invent 大会第一天,看看AWS有哪些最新进展?\n
  5. HTML 块标签,行内标签,行内块标签以及之间的相互转换
  6. django 2.0 url匹配
  7. New Linux2.6 I2C Driver Model Example
  8. 浅谈HTTP响应拆分攻击(一)
  9. 组件接口(API)设计指南-文件夹
  10. nginx 压缩和缓存设置