Java Code Examples for org.springframework.core.ResolvableType#resolve()
The following examples show how to use
org.springframework.core.ResolvableType#resolve() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ReturnTypeParser.java From springdoc-openapi with Apache License 2.0 | 6 votes |
/** * Resolve variable resolvable type. * * @param typeVariable the type variable * @param contextType the context type * @return the resolvable type */ static ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) { ResolvableType resolvedType; if (contextType.hasGenerics()) { resolvedType = ResolvableType.forType(typeVariable, contextType); if (resolvedType.resolve() != null) { return resolvedType; } } ResolvableType superType = contextType.getSuperType(); if (superType != ResolvableType.NONE) { resolvedType = resolveVariable(typeVariable, superType); if (resolvedType.resolve() != null) { return resolvedType; } } for (ResolvableType ifc : contextType.getInterfaces()) { resolvedType = resolveVariable(typeVariable, ifc); if (resolvedType.resolve() != null) { return resolvedType; } } return ResolvableType.NONE; }
Example 2
Source File: GenericTypeAwareAutowireCandidateResolver.java From java-technology-stack with MIT License | 6 votes |
@Nullable protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, DependencyDescriptor descriptor) { // Should typically be set for any kind of factory method, since the BeanFactory // pre-resolves them before reaching out to the AutowireCandidateResolver... ResolvableType returnType = rbd.factoryMethodReturnType; if (returnType == null) { Method factoryMethod = rbd.getResolvedFactoryMethod(); if (factoryMethod != null) { returnType = ResolvableType.forMethodReturnType(factoryMethod); } } if (returnType != null) { Class<?> resolvedClass = returnType.resolve(); if (resolvedClass != null && descriptor.getDependencyType().isAssignableFrom(resolvedClass)) { // Only use factory method metadata if the return type is actually expressive enough // for our dependency. Otherwise, the returned instance type may have matched instead // in case of a singleton instance having been registered with the container already. return returnType; } } return null; }
Example 3
Source File: AbstractJackson2HttpMessageConverter.java From lams with GNU General Public License v2.0 | 6 votes |
private ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) { ResolvableType resolvedType; if (contextType.hasGenerics()) { resolvedType = ResolvableType.forType(typeVariable, contextType); if (resolvedType.resolve() != null) { return resolvedType; } } ResolvableType superType = contextType.getSuperType(); if (superType != ResolvableType.NONE) { resolvedType = resolveVariable(typeVariable, superType); if (resolvedType.resolve() != null) { return resolvedType; } } for (ResolvableType ifc : contextType.getInterfaces()) { resolvedType = resolveVariable(typeVariable, ifc); if (resolvedType.resolve() != null) { return resolvedType; } } return ResolvableType.NONE; }
Example 4
Source File: StaticListableBeanFactory.java From java-technology-stack with MIT License | 5 votes |
@Override public String[] getBeanNamesForType(@Nullable ResolvableType type) { boolean isFactoryType = false; if (type != null) { Class<?> resolved = type.resolve(); if (resolved != null && FactoryBean.class.isAssignableFrom(resolved)) { isFactoryType = true; } } List<String> matches = new ArrayList<>(); for (Map.Entry<String, Object> entry : this.beans.entrySet()) { String name = entry.getKey(); Object beanInstance = entry.getValue(); if (beanInstance instanceof FactoryBean && !isFactoryType) { Class<?> objectType = ((FactoryBean<?>) beanInstance).getObjectType(); if (objectType != null && (type == null || type.isAssignableFrom(objectType))) { matches.add(name); } } else { if (type == null || type.isInstance(beanInstance)) { matches.add(name); } } } return StringUtils.toStringArray(matches); }
Example 5
Source File: GenericApplicationListenerAdapter.java From java-technology-stack with MIT License | 5 votes |
@Override @SuppressWarnings("unchecked") public boolean supportsEventType(ResolvableType eventType) { if (this.delegate instanceof SmartApplicationListener) { Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve(); return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass)); } else { return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType)); } }
Example 6
Source File: MicronautBeanFactory.java From micronaut-spring with Apache License 2.0 | 5 votes |
@Override public @Nonnull String[] getBeanNamesForType(@Nonnull ResolvableType type) { final Class<?> resolved = type.resolve(); if (resolved != null) { return getBeanNamesForType(resolved); } return StringUtils.EMPTY_STRING_ARRAY; }
Example 7
Source File: VaadinControlInitializer.java From jdal with Apache License 2.0 | 5 votes |
/** * {@inheritDoc} */ public void initialize(Object control, String property, InitializationConfig config) { if (this.dao == null) { log.warn("Nothing to do without persistent service"); return; } Class<?> clazz = config.getType(); PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(clazz, property); if (pd == null) { log.error("Not found property descriptor for property [" + property + "]") ; return; } ResolvableType propertyType = ResolvableType.forMethodReturnType(pd.getReadMethod()); Annotation[] annotations = getAnnotations(property, clazz); for (Annotation a : annotations) { List<Object> items = null; if (ManyToOne.class.equals(a.annotationType()) || ManyToMany.class.equals(a.annotationType()) ) { items = getEntityList(propertyType, config.getSortPropertyName()); } else if (Reference.class.equals(a.annotationType())) { Reference r = (Reference) a; Class<?> type = void.class.equals(r.target()) ? propertyType.resolve() : r.target(); List<Object> entities = getEntityList(type, config.getSortPropertyName()); items = StringUtils.isEmpty(r.property()) ? entities : getValueList(entities, r.property()); } if (items != null) { if (control instanceof AbstractSelect) { for (Object item : items) ((AbstractSelect) control).addItem(item); } break; } } }
Example 8
Source File: SolaceJmsAutoConfigurationTestBase.java From solace-jms-spring-boot with Apache License 2.0 | 5 votes |
static Set<Object[]> getTestParameters(Set<ResolvableType> testClasses) { Set<Object[]> parameters = new HashSet<>(); for (ResolvableType resolvableRawClass : testClasses) { Class<?> rawClass = resolvableRawClass.resolve(); StringBuilder testName = new StringBuilder(rawClass.getSimpleName()); for (ResolvableType resolvableGeneric : resolvableRawClass.getGenerics()) { Class<?> genericClass = resolvableGeneric.getRawClass(); if (genericClass != null) testName = testName.append('—').append(genericClass.getSimpleName()); } parameters.add(new Object[]{testName.toString(), rawClass}); } return parameters; }
Example 9
Source File: StaticListableBeanFactory.java From spring-analysis-note with MIT License | 5 votes |
@Override public String[] getBeanNamesForType(@Nullable ResolvableType type) { boolean isFactoryType = false; if (type != null) { Class<?> resolved = type.resolve(); if (resolved != null && FactoryBean.class.isAssignableFrom(resolved)) { isFactoryType = true; } } List<String> matches = new ArrayList<>(); for (Map.Entry<String, Object> entry : this.beans.entrySet()) { String name = entry.getKey(); Object beanInstance = entry.getValue(); if (beanInstance instanceof FactoryBean && !isFactoryType) { Class<?> objectType = ((FactoryBean<?>) beanInstance).getObjectType(); if (objectType != null && (type == null || type.isAssignableFrom(objectType))) { matches.add(name); } } else { if (type == null || type.isInstance(beanInstance)) { matches.add(name); } } } return StringUtils.toStringArray(matches); }
Example 10
Source File: CarHandler.java From tutorials with MIT License | 5 votes |
public List<Vehicle> getVehicles() throws NoSuchFieldException { ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles")); System.out.println(vehiclesType); ResolvableType type = vehiclesType.getGeneric(); System.out.println(type); Class<?> aClass = type.resolve(); System.out.println(aClass); return this.vehicles; }
Example 11
Source File: RootBeanDefinition.java From java-technology-stack with MIT License | 5 votes |
/** * Return the target type of this bean definition, if known * (either specified in advance or resolved on first instantiation). * @since 3.2.2 */ @Nullable public Class<?> getTargetType() { if (this.resolvedTargetType != null) { return this.resolvedTargetType; } ResolvableType targetType = this.targetType; return (targetType != null ? targetType.resolve() : null); }
Example 12
Source File: ServerSentEventHttpMessageReader.java From java-technology-stack with MIT License | 5 votes |
@Override public Mono<Object> readMono( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { // We're ahead of String + "*/*" // Let's see if we can aggregate the output (lest we time out)... if (elementType.resolve() == String.class) { Flux<DataBuffer> body = message.getBody(); return stringDecoder.decodeToMono(body, elementType, null, null).cast(Object.class); } return Mono.error(new UnsupportedOperationException( "ServerSentEventHttpMessageReader only supports reading stream of events as a Flux")); }
Example 13
Source File: SpringMvcContract.java From spring-cloud-openfeign with Apache License 2.0 | 5 votes |
private static TypeDescriptor getElementTypeDescriptor( TypeDescriptor typeDescriptor) { TypeDescriptor elementTypeDescriptor = typeDescriptor.getElementTypeDescriptor(); // that means it's not a collection but it is iterable, gh-135 if (elementTypeDescriptor == null && Iterable.class.isAssignableFrom(typeDescriptor.getType())) { ResolvableType type = typeDescriptor.getResolvableType().as(Iterable.class) .getGeneric(0); if (type.resolve() == null) { return null; } return new TypeDescriptor(type, null, typeDescriptor.getAnnotations()); } return elementTypeDescriptor; }
Example 14
Source File: AbstractEncoderMethodReturnValueHandler.java From spring-analysis-note with MIT License | 5 votes |
@SuppressWarnings("unchecked") private Flux<DataBuffer> encodeContent( @Nullable Object content, MethodParameter returnType, DataBufferFactory bufferFactory, @Nullable MimeType mimeType, Map<String, Object> hints) { ResolvableType returnValueType = ResolvableType.forMethodParameter(returnType); ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnValueType.resolve(), content); Publisher<?> publisher; ResolvableType elementType; if (adapter != null) { publisher = adapter.toPublisher(content); boolean isUnwrapped = KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(returnType.getContainingClass()) && KotlinDelegate.isSuspend(returnType.getMethod()) && !COROUTINES_FLOW_CLASS_NAME.equals(returnValueType.toClass().getName()); ResolvableType genericType = isUnwrapped ? returnValueType : returnValueType.getGeneric(); elementType = getElementType(adapter, genericType); } else { publisher = Mono.justOrEmpty(content); elementType = (returnValueType.toClass() == Object.class && content != null ? ResolvableType.forInstance(content) : returnValueType); } if (elementType.resolve() == void.class || elementType.resolve() == Void.class) { return Flux.from(publisher).cast(DataBuffer.class); } Encoder<?> encoder = getEncoder(elementType, mimeType); return Flux.from((Publisher) publisher).map(value -> encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints)); }
Example 15
Source File: PayloadMethodArgumentResolver.java From spring-analysis-note with MIT License | 4 votes |
private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message, boolean isContentRequired, Flux<DataBuffer> content, MimeType mimeType) { ResolvableType targetType = ResolvableType.forMethodParameter(parameter); Class<?> resolvedType = targetType.resolve(); ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null); ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType); isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty()); Consumer<Object> validator = getValidator(message, parameter); Map<String, Object> hints = Collections.emptyMap(); for (Decoder<?> decoder : this.decoders) { if (decoder.canDecode(elementType, mimeType)) { if (adapter != null && adapter.isMultiValue()) { Flux<?> flux = content .map(buffer -> decoder.decode(buffer, elementType, mimeType, hints)) .onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex))); if (isContentRequired) { flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message))); } if (validator != null) { flux = flux.doOnNext(validator); } return Mono.just(adapter.fromPublisher(flux)); } else { // Single-value (with or without reactive type wrapper) Mono<?> mono = content.next() .map(buffer -> decoder.decode(buffer, elementType, mimeType, hints)) .onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex))); if (isContentRequired) { mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message))); } if (validator != null) { mono = mono.doOnNext(validator); } return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono)); } } } return Mono.error(new MethodArgumentResolutionException( message, parameter, "Cannot decode to [" + targetType + "]" + message)); }
Example 16
Source File: StringDecoder.java From spring-analysis-note with MIT License | 4 votes |
@Override public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) { return (elementType.resolve() == String.class && super.canDecode(elementType, mimeType)); }
Example 17
Source File: GenericsUtils.java From spring-cloud-stream with Apache License 2.0 | 4 votes |
/** * For a specific class that implements or extends a parameterized type, return the * parameter of that interface at a given position. For example, for this class: * * <pre> {@code * class MessageChannelBinder implements Binder<MessageChannel, ?, ?> * } </pre> * * <pre> {@code * getParameterType(MessageChannelBinder.class, Binder.class, 0); * } </pre> * * will return {@code Binder} * @param evaluatedClass the evaluated class * @param interfaceClass the parametrized interface * @param position the position * @return the parameter type if any * @throws IllegalStateException if the evaluated class does not implement the * interface or */ public static Class<?> getParameterType(Class<?> evaluatedClass, Class<?> interfaceClass, int position) { Class<?> bindableType = null; Assert.isTrue(interfaceClass.isInterface(), "'interfaceClass' must be an interface"); if (!interfaceClass.isAssignableFrom(evaluatedClass)) { throw new IllegalStateException( evaluatedClass + " does not implement " + interfaceClass); } ResolvableType currentType = ResolvableType.forType(evaluatedClass); while (!Object.class.equals(currentType.getRawClass()) && bindableType == null) { ResolvableType[] interfaces = currentType.getInterfaces(); ResolvableType resolvableType = null; for (ResolvableType interfaceType : interfaces) { if (interfaceClass.equals(interfaceType.getRawClass())) { resolvableType = interfaceType; break; } } if (resolvableType == null) { currentType = currentType.getSuperType(); } else { ResolvableType[] generics = resolvableType.getGenerics(); ResolvableType generic = generics[position]; Class<?> resolvedParameter = generic.resolve(); if (resolvedParameter != null) { bindableType = resolvedParameter; } else { bindableType = Object.class; } } } if (bindableType == null) { throw new IllegalStateException( "Cannot find parameter of " + evaluatedClass.getName() + " for " + interfaceClass + " at position " + position); } return bindableType; }
Example 18
Source File: AbstractMessageReaderArgumentResolver.java From spring-analysis-note with MIT License | 4 votes |
/** * Read the body from a method argument with {@link HttpMessageReader}. * @param bodyParam represents the element type for the body * @param actualParam the actual method argument type; possibly different * from {@code bodyParam}, e.g. for an {@code HttpEntity} argument * @param isBodyRequired true if the body is required * @param bindingContext the binding context to use * @param exchange the current exchange * @return a Mono with the value to use for the method argument * @since 5.0.2 */ protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam, boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) { ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam); ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType); Class<?> resolvedType = bodyType.resolve(); ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null); ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType); isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty()); ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); MediaType contentType = request.getHeaders().getContentType(); MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM); Object[] hints = extractValidationHints(bodyParam); if (mediaType.isCompatibleWith(MediaType.APPLICATION_FORM_URLENCODED)) { return Mono.error(new IllegalStateException( "In a WebFlux application, form data is accessed via ServerWebExchange.getFormData().")); } if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + (contentType != null ? "Content-Type:" + contentType : "No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM)); } for (HttpMessageReader<?> reader : getMessageReaders()) { if (reader.canRead(elementType, mediaType)) { Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix()); if (adapter != null && adapter.isMultiValue()) { if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]"); } Flux<?> flux = reader.read(actualType, elementType, request, response, readHints); flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex))); if (isBodyRequired) { flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam))); } if (hints != null) { flux = flux.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange)); } return Mono.just(adapter.fromPublisher(flux)); } else { // Single-value (with or without reactive type wrapper) if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]"); } Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints); mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex))); if (isBodyRequired) { mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam))); } if (hints != null) { mono = mono.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange)); } return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono)); } } } // No compatible reader but body may be empty.. HttpMethod method = request.getMethod(); if (contentType == null && method != null && SUPPORTED_METHODS.contains(method)) { Flux<DataBuffer> body = request.getBody().doOnNext(buffer -> { DataBufferUtils.release(buffer); // Body not empty, back to 415.. throw new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType); }); if (isBodyRequired) { body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam))); } return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body)); } return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType)); }
Example 19
Source File: AbstractMessageReaderArgumentResolver.java From java-technology-stack with MIT License | 4 votes |
/** * Read the body from a method argument with {@link HttpMessageReader}. * @param bodyParam represents the element type for the body * @param actualParam the actual method argument type; possibly different * from {@code bodyParam}, e.g. for an {@code HttpEntity} argument * @param isBodyRequired true if the body is required * @param bindingContext the binding context to use * @param exchange the current exchange * @return a Mono with the value to use for the method argument * @since 5.0.2 */ protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam, boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) { ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam); ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType); Class<?> resolvedType = bodyType.resolve(); ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null); ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType); isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty()); ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); MediaType contentType = request.getHeaders().getContentType(); MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM); Object[] hints = extractValidationHints(bodyParam); if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + (contentType != null ? "Content-Type:" + contentType : "No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM)); } for (HttpMessageReader<?> reader : getMessageReaders()) { if (reader.canRead(elementType, mediaType)) { Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix()); if (adapter != null && adapter.isMultiValue()) { if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]"); } Flux<?> flux = reader.read(actualType, elementType, request, response, readHints); flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex))); if (isBodyRequired) { flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam))); } if (hints != null) { flux = flux.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange)); } return Mono.just(adapter.fromPublisher(flux)); } else { // Single-value (with or without reactive type wrapper) if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]"); } Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints); mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex))); if (isBodyRequired) { mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam))); } if (hints != null) { mono = mono.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange)); } return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono)); } } } // No compatible reader but body may be empty.. HttpMethod method = request.getMethod(); if (contentType == null && method != null && SUPPORTED_METHODS.contains(method)) { Flux<DataBuffer> body = request.getBody().doOnNext(o -> { // Body not empty, back to 415.. throw new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType); }); if (isBodyRequired) { body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam))); } return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body)); } return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType)); }
Example 20
Source File: MultipartHttpMessageWriter.java From java-technology-stack with MIT License | 4 votes |
@SuppressWarnings("unchecked") private <T> Flux<DataBuffer> encodePart(byte[] boundary, String name, T value) { MultipartHttpOutputMessage outputMessage = new MultipartHttpOutputMessage(this.bufferFactory, getCharset()); HttpHeaders outputHeaders = outputMessage.getHeaders(); T body; ResolvableType resolvableType = null; if (value instanceof HttpEntity) { HttpEntity<T> httpEntity = (HttpEntity<T>) value; outputHeaders.putAll(httpEntity.getHeaders()); body = httpEntity.getBody(); Assert.state(body != null, "MultipartHttpMessageWriter only supports HttpEntity with body"); if (httpEntity instanceof MultipartBodyBuilder.PublisherEntity<?, ?>) { MultipartBodyBuilder.PublisherEntity<?, ?> publisherEntity = (MultipartBodyBuilder.PublisherEntity<?, ?>) httpEntity; resolvableType = publisherEntity.getResolvableType(); } } else { body = value; } if (resolvableType == null) { resolvableType = ResolvableType.forClass(body.getClass()); } if (!outputHeaders.containsKey(HttpHeaders.CONTENT_DISPOSITION)) { if (body instanceof Resource) { outputHeaders.setContentDispositionFormData(name, ((Resource) body).getFilename()); } else if (resolvableType.resolve() == Resource.class) { body = (T) Mono.from((Publisher<?>) body).doOnNext(o -> outputHeaders .setContentDispositionFormData(name, ((Resource) o).getFilename())); } else { outputHeaders.setContentDispositionFormData(name, null); } } MediaType contentType = outputHeaders.getContentType(); final ResolvableType finalBodyType = resolvableType; Optional<HttpMessageWriter<?>> writer = this.partWriters.stream() .filter(partWriter -> partWriter.canWrite(finalBodyType, contentType)) .findFirst(); if (!writer.isPresent()) { return Flux.error(new CodecException("No suitable writer found for part: " + name)); } Publisher<T> bodyPublisher = body instanceof Publisher ? (Publisher<T>) body : Mono.just(body); // The writer will call MultipartHttpOutputMessage#write which doesn't actually write // but only stores the body Flux and returns Mono.empty(). Mono<Void> partContentReady = ((HttpMessageWriter<T>) writer.get()) .write(bodyPublisher, resolvableType, contentType, outputMessage, DEFAULT_HINTS); // After partContentReady, we can access the part content from MultipartHttpOutputMessage // and use it for writing to the actual request body Flux<DataBuffer> partContent = partContentReady.thenMany(Flux.defer(outputMessage::getBody)); return Flux.concat(Mono.just(generateBoundaryLine(boundary)), partContent, Mono.just(generateNewLine())); }