webflux系列--源码解析二
生活随笔
收集整理的這篇文章主要介紹了
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系列--源码解析二的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webflux系列--基础
- 下一篇: webflux系列--reactor源码