日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

webflux系列--源码解析二

發布時間:2024/4/13 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 webflux系列--源码解析二 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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系列--源码解析二的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。