HttpMessageConverter<T> class
abstract
Strategy interface for converting between HTTP messages and Dart objects.
HttpMessageConverter implementations are responsible for the two-way conversion between HTTP request/response bodies and Dart objects. This abstraction enables content negotiation, serialization, and deserialization in a type-safe manner throughout the Jetleaf framework.
Generic Type Parameter
T: The Dart type that this converter can read and write
Primary Responsibilities
- Deserialization: Convert HTTP request bodies to Dart objects (read)
- Serialization: Convert Dart objects to HTTP response bodies (write)
- Content Negotiation: Determine supported media types for specific types
- Type Safety: Ensure proper type handling during conversion
Framework Integration
Converters are used by:
- Request Body Processing: Converting JSON/XML request bodies to method parameters
- Response Body Processing: Converting return values to JSON/XML responses
- Content Negotiation: Selecting appropriate converters based on Accept headers
- Error Handling: Providing meaningful conversion error messages
Built-in Implementations
Jetleaf typically provides these standard converters:
JsonHttpMessageConverter: Handles JSON ↔ Dart object conversionStringHttpMessageConverter: Handles text/plain contentFormHttpMessageConverter: Handles application/x-www-form-urlencodedByteArrayHttpMessageConverter: Handles binary data (application/octet-stream)XmlHttpMessageConverter: Handles XML content (application/xml)
Example: JSON Converter Implementation
@Generic(HttpMessageConverter)
class JsonHttpMessageConverter implements HttpMessageConverter<Object> {
final JsonCodec _codec;
JsonHttpMessageConverter(this._codec);
@override
bool canRead(Class<Object> type, [MediaType? mediaType]) {
return mediaType?.includes(MediaType.APPLICATION_JSON) ?? true;
}
@override
bool canWrite(Class<Object> type, [MediaType? mediaType]) {
return mediaType?.includes(MediaType.APPLICATION_JSON) ?? true;
}
@override
List<MediaType> getSupportedMediaTypes() {
return [MediaType.APPLICATION_JSON];
}
@override
Future<Object> read(Class<Object> type, HttpInputMessage inputMessage) async {
try {
final body = await inputMessage.getBody().readAsString();
return _codec.decode(body);
} catch (e) {
throw HttpMessageNotReadableException('Failed to read JSON: $e', e);
}
}
@override
Future<void> write(Object object, MediaType? contentType, HttpOutputMessage outputMessage) async {
try {
final json = _codec.encode(object);
outputMessage.getHeaders().setContentType(contentType ?? MediaType.APPLICATION_JSON);
await outputMessage.getBody().writeString(json);
} catch (e) {
throw HttpMessageNotWritableException('Failed to write JSON: $e', e);
}
}
}
Content Negotiation Process
When processing requests/responses, the framework:
- Collects Media Types: From Accept header or Content-Type header
- Finds Compatible Converters: Using canRead/canWrite methods
- Selects Best Match: Based on media type specificity and quality factors
- Executes Conversion: Using the selected converter
Error Handling
Converters should throw framework-specific exceptions:
- HttpMessageNotReadableException: When deserialization fails
- HttpMessageNotWritableException: When serialization fails
IOException: For I/O-related errors during stream processing
Best Practices
- Make canRead and canWrite checks efficient and fast
- Support common media type variations (e.g., application/json vs application/vnd.api+json)
- Handle character encoding properly for text-based formats
- Consider performance implications for large payloads
- Provide clear error messages for debugging conversion issues
- Implementers
- Annotations
-
- @Generic.new(HttpMessageConverter)
Constructors
- HttpMessageConverter()
-
Strategy interface for converting between HTTP messages and Dart objects.
const
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
-
canRead(
Class type, [MediaType? mediaType]) → bool - Determines whether this converter can deserialize the given type from the specified media type.
-
canWrite(
Class type, [MediaType? mediaType]) → bool - Determines whether this converter can serialize the given type to the specified media type.
-
equalizedProperties(
) → List< Object?> -
Mixin-style contract for value-based equality,
hashCode, andtoString.inherited -
getClassSupportedMediaTypes(
Class< T> type) → List<MediaType> - Returns the media types specifically supported for a given class type.
-
getSupportedMediaTypes(
) → List< MediaType> - Returns the list of media types this converter supports by default.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
read(
Class< T> type, HttpInputMessage inputMessage) → Future<T> -
Deserializes an HTTP input message to a Dart object of type
T. -
toString(
) → String -
A string representation of this object.
inherited
-
write(
T object, MediaType? contentType, HttpOutputMessage outputMessage) → Future< void> - Serializes a Dart object to an HTTP output message.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited