@Nullable private Object getObjectToRender(@Nullable Map<String, ?> model) { if (model == null) { return null; } Map<String, ?> result = model.entrySet().stream() .filter(this::isMatch) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); if (result.isEmpty()) { return null; } else if (result.size() == 1) { return result.values().iterator().next(); } else if (this.canWriteMap) { return result; } else { throw new IllegalStateException("Multiple matches found: " + result + " but " + "Map rendering is not supported by " + getMessageWriter().getClass().getName()); } }
private boolean isMatch(Map.Entry<String, ?> entry) { if (entry.getValue() == null) { return false; } if (!getModelKeys().isEmpty() && !getModelKeys().contains(entry.getKey())) { return false; } ResolvableType type = ResolvableType.forInstance(entry.getValue()); return getMessageWriter().canWrite(type, null); }
protected Object extractObjectToRender(Map<String, ?> model) { Map<String, Object> map = new HashMap<>(model.size()); for (Map.Entry<String, ?> entry : model.entrySet()) { if (isEligibleAttribute(entry.getKey(), entry.getValue())) { map.put(entry.getKey(), entry.getValue()); } } if (map.isEmpty()) { return null; } else if (map.size() == 1) { return map.values().iterator().next(); } else if (getMessageWriter().canWrite(ResolvableType.forClass(Map.class), null)) { return map; } else { throw new IllegalStateException( "Multiple matching attributes found: " + map + ". " + "However Map rendering is not supported by " + getMessageWriter()); } }
@SuppressWarnings("unchecked") private <T> Mono<Void> applyMessageWriter(Object value, MediaType contentType, ServerWebExchange exchange) { if (value == null) { return Mono.empty(); } Publisher<? extends T> stream = Mono.just((T) value); ResolvableType type = ResolvableType.forClass(value.getClass()); ServerHttpResponse response = exchange.getResponse(); return ((HttpMessageWriter<T>) getMessageWriter()).write(stream, type, contentType, response, Collections.emptyMap()); }
/** * Whether the given model attribute key-value pair is eligible for encoding. * <p>The default implementation checks against the configured * {@link #setModelKeys model keys} and whether the Encoder supports the * value type. */ protected boolean isEligibleAttribute(String attributeName, Object attributeValue) { ResolvableType type = ResolvableType.forClass(attributeValue.getClass()); if (getModelKeys().isEmpty()) { return getMessageWriter().canWrite(type, null); } if (getModelKeys().contains(attributeName)) { if (getMessageWriter().canWrite(type, null)) { return true; } throw new IllegalStateException( "Model object [" + attributeValue + "] retrieved via key " + "[" + attributeName + "] is not supported by " + getMessageWriter()); } return false; }