HttpMessageConverters class final
A composite registry and container for managing HttpMessageConverter pods.
Overview
The HttpMessageConverters serves as the central hub for HTTP message converter management in the Jetleaf framework. It implements multiple roles:
- Registry Interface: Allows programmatic converter registration via add
- Container: Maintains an ordered collection of all available converters
- Discovery Engine: Automatically discovers converters and registrars from the application context
- Ordering Service: Applies proper ordering to converters for content negotiation
Key Responsibilities
- Automatic Discovery: Finds all HttpMessageConverter and HttpMessageConverterRegistrar pods
- Deduplication: Ensures each converter is registered only once
- Order Management: Applies
AnnotationAwareOrderComparatorfor proper converter priority - Lifecycle Integration: Implements
SmartInitializingSingletonfor startup initialization - Framework Integration: Implements
ApplicationContextAwarefor dependency access
Framework Integration Flow
During application startup:
- Context Awareness: Framework injects
ApplicationContextvia setApplicationContext - Pod Initialization: Framework calls onReady when context is ready
- Registrar Discovery: Finds and invokes all HttpMessageConverterRegistrar pods
- Converter Discovery: Finds and registers all HttpMessageConverter pods
- Ordering Application: Sorts converters using
AnnotationAwareOrderComparator - Ready State: Converter collection becomes available via getMessageConverters
Example: Manual Registration
@Pod
class CustomConverterSetup {
final HttpMessageConverters _compositeConverter;
CustomConverterSetup(this._compositeConverter);
@PostConstruct
void setupConverters() {
// Manually register custom converters
_compositeConverter.add(CustomJsonConverter());
_compositeConverter.add(ProtobufConverter());
}
}
Example: Registrar-Based Registration
@Pod
class CustomConverterRegistrar implements HttpMessageConverterRegistrar {
@override
void register(HttpMessageConverterRegistry registry) {
registry.add(CustomJsonConverter());
registry.add(ProtobufConverter());
}
}
// The HttpMessageConverters will automatically discover
// and invoke this registrar during onReady()
Converter Ordering Strategy
Converters are ordered using AnnotationAwareOrderComparator which considers:
@Orderannotations on converter classes@Priorityannotations on converter classes- Natural ordering based on converter capabilities
- Registration order as fallback
Typical Converter Order
The framework typically orders converters by specificity:
- ByteArrayHttpMessageConverter - Most specific (binary data)
- StringHttpMessageConverter - Text content
- FormHttpMessageConverter - Form data
- JsonHttpMessageConverter - JSON data
- XmlHttpMessageConverter - XML data
- Generic Converters - Least specific/catch-all
Content Negotiation Process
When processing HTTP messages, the framework:
- Retrieves Converters: Gets ordered list via getMessageConverters()
- Iterates in Order: Processes converters from most to least specific
- First Match Wins: Uses the first converter that can handle the media type
- Fallback Handling: May use default converters if no specific match found
Thread Safety
The implementation uses synchronization for concurrent access:
- Converter registration is thread-safe via
synchronized - Converter retrieval provides an unmodifiable view
- Once initialized, the converter list is effectively immutable
Error Handling
- Duplicate Converters: Silently deduplicated during registration
- Self-Registration: HttpMessageConverters ignores itself during discovery
- Missing Context: Fails gracefully if application context not set
- Empty Registry: Handles scenarios with no converters gracefully
Best Practices
- Use registrars for modular converter configuration
- Apply
@Orderannotations for explicit priority control - Register specific converters before generic ones
- Consider performance implications of large converter collections
- Test content negotiation with your specific converter mix
Integration Example
@Pod
class HttpMessageProcessor {
final HttpMessageConverters _converter;
HttpMessageProcessor(this._converter);
Future<void> processRequest(HttpInputMessage request, HttpOutputMessage response) async {
final converters = _converter.getMessageConverters();
// Use converters for content negotiation and processing
for (final converter in converters) {
if (converter.canRead(User.class, request.headers.contentType)) {
final user = await converter.read(User.class, request);
// Process user...
break;
}
}
}
}
Related Components
- HttpMessageConverter: Strategy interface for message conversion
- HttpMessageConverterRegistry: Registration interface
- HttpMessageConverterRegistrar: Modular registration pattern
AnnotationAwareOrderComparator: Ordering utility for convertersApplicationContext: Dependency injection and pod management
Summary
The HttpMessageConverters provides a robust, auto-discovering, ordered container for HTTP message converters, serving as the cornerstone of Jetleaf's content negotiation and message processing capabilities.
- Implemented types
Constructors
- HttpMessageConverters()
- A composite registry and container for managing HttpMessageConverter pods.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
add(
HttpMessageConverter converter) → void -
Registers a HttpMessageConverter instance with this registry.
override
-
findReadable(
Class type, MediaType? mediaType) → HttpMessageConverter? - Finds the first HttpMessageConverter capable of reading the given type.
-
findWritable(
Class type, MediaType mediaType) → HttpMessageConverter? - Finds the first HttpMessageConverter capable of writing the given type.
-
getMessageConverters(
) → List< HttpMessageConverter> - Returns an ordered, unmodifiable list of all registered message converters.
-
getPackageName(
) → String - Represents an abstraction for identifying the package that an object, resource, or service belongs to.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
onReady(
) → Future< void> - Interface to be implemented by pods that require initialization logic after their properties have been set by the container.
-
setApplicationContext(
ApplicationContext applicationContext) → void -
Sets the
ApplicationContextthat this component runs in. -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited