CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework--spring-web

Spring Web module providing web application infrastructure including HTTP integration, servlet filters, Spring web MVC framework, and reactive web stack support

Overview
Eval results
Files

message-conversion.mddocs/

Message Conversion

HTTP message conversion and encoding support for transforming between Java objects and HTTP message bodies. Includes both servlet-based converters for traditional web applications and reactive codecs for streaming applications.

Capabilities

HTTP Message Converters (Servlet-Based)

Traditional message converters for converting between HTTP messages and Java objects in servlet-based applications.

/**
 * Contract for HTTP message converters
 */
interface HttpMessageConverter<T> {
    /** Check if this converter can read the given class and media type */
    boolean canRead(Class<?> clazz, MediaType mediaType);
    /** Check if this converter can write the given class and media type */
    boolean canWrite(Class<?> clazz, MediaType mediaType);
    /** Get the supported media types for this converter */
    List<MediaType> getSupportedMediaTypes();
    
    /** Read object from HTTP input message */
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage) 
        throws IOException, HttpMessageNotReadableException;
    /** Write object to HTTP output message */
    void write(T t, MediaType contentType, HttpOutputMessage outputMessage) 
        throws IOException, HttpMessageNotWritableException;
}

/**
 * Generic version supporting parameterized types
 */
interface GenericHttpMessageConverter<T> extends HttpMessageConverter<T> {
    /** Check if converter can read the generic type */
    boolean canRead(Type type, Class<?> contextClass, MediaType mediaType);
    /** Check if converter can write the generic type */
    boolean canWrite(Type type, Class<?> clazz, MediaType mediaType);
    
    /** Read generic type from HTTP message */
    T read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) 
        throws IOException, HttpMessageNotReadableException;
    /** Write generic type to HTTP message */
    void write(T t, Type type, MediaType contentType, HttpOutputMessage outputMessage) 
        throws IOException, HttpMessageNotWritableException;
}

Common Message Converter Implementations

Built-in converters for common data formats and types.

/**
 * Base class for message converter implementations
 */
abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {
    protected AbstractHttpMessageConverter(MediaType supportedMediaType);
    protected AbstractHttpMessageConverter(MediaType... supportedMediaTypes);
    
    /** Set supported media types */
    void setSupportedMediaTypes(List<MediaType> supportedMediaTypes);
    /** Get supported media types */
    List<MediaType> getSupportedMediaTypes();
    
    // Template methods for subclasses
    protected abstract boolean supports(Class<?> clazz);
    protected abstract T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) 
        throws IOException, HttpMessageNotReadableException;
    protected abstract void writeInternal(T t, HttpOutputMessage outputMessage) 
        throws IOException, HttpMessageNotWritableException;
}

/**
 * String message converter
 */
class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
    StringHttpMessageConverter();
    StringHttpMessageConverter(Charset defaultCharset);
    
    /** Set whether to write Accept-Charset header */
    void setWriteAcceptCharset(boolean writeAcceptCharset);
    /** Set available charsets for Accept-Charset header */
    void setAvailableCharsets(List<Charset> availableCharsets);
}

/**
 * Byte array message converter
 */
class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<byte[]> {
    ByteArrayHttpMessageConverter();
    
    // Supports application/octet-stream and all other media types
}

/**
 * Resource message converter
 */
class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<Resource> {
    ResourceHttpMessageConverter();
    ResourceHttpMessageConverter(boolean supportsReadStreaming);
    
    // Automatically detects content type from resource
}

/**
 * Form data message converter
 */
class FormHttpMessageConverter implements HttpMessageConverter<MultiValueMap<String, ?>> {
    FormHttpMessageConverter();
    
    /** Set default charset for form encoding */
    void setCharset(Charset charset);
    /** Set supported media types */
    void setSupportedMediaTypes(List<MediaType> supportedMediaTypes);
    /** Set multipart character sets */
    void setMultipartCharsets(Map<String, Charset> multipartCharsets);
}

/**
 * Enhanced form converter with multipart support
 */
class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter {
    AllEncompassingFormHttpMessageConverter();
    
    // Adds support for multipart/form-data with part converters
}

JSON Message Converters

Converters for JSON serialization using popular libraries.

/**
 * Jackson 2 JSON message converter
 */
class MappingJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
    MappingJackson2HttpMessageConverter();
    MappingJackson2HttpMessageConverter(ObjectMapper objectMapper);
    
    /** Set the ObjectMapper to use */
    void setObjectMapper(ObjectMapper objectMapper);
    /** Get the current ObjectMapper */
    ObjectMapper getObjectMapper();
    
    /** Set JSON prefix for security */
    void setJsonPrefix(String jsonPrefix);
    /** Set whether to prefix JSON output */
    void setPrefixJson(boolean prefixJson);
}

/**
 * Base class for Jackson converters
 */
abstract class AbstractJackson2HttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {
    /** Set pretty print formatting */
    void setPrettyPrint(boolean prettyPrint);
    /** Add supported media types */
    protected void addDefaultMediaTypes(MediaType... mediaTypes);
}

/**
 * Google Gson JSON message converter
 */
class GsonHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {
    GsonHttpMessageConverter();
    GsonHttpMessageConverter(Gson gson);
    
    /** Set the Gson instance to use */
    void setGson(Gson gson);
    /** Get the current Gson instance */
    Gson getGson();
    
    /** Set JSON prefix for security */
    void setJsonPrefix(String jsonPrefix);
}

/**
 * JSON-B message converter
 */
class JsonbHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {
    JsonbHttpMessageConverter();
    JsonbHttpMessageConverter(Jsonb jsonb);
    
    /** Set the Jsonb instance to use */
    void setJsonb(Jsonb jsonb);
    /** Get the current Jsonb instance */
    Jsonb getJsonb();
}

XML Message Converters

Converters for XML serialization and deserialization.

/**
 * JAXB2 XML message converter
 */
class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessageConverter<Object> {
    Jaxb2RootElementHttpMessageConverter();
    
    // Supports classes annotated with @XmlRootElement or @XmlType
}

/**
 * Marshalling XML message converter using Spring's marshalling abstractions
 */
class MarshallingHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
    MarshallingHttpMessageConverter();
    MarshallingHttpMessageConverter(Marshaller marshaller);
    MarshallingHttpMessageConverter(Marshaller marshaller, Unmarshaller unmarshaller);
    
    /** Set the marshaller for writing XML */
    void setMarshaller(Marshaller marshaller);
    /** Set the unmarshaller for reading XML */
    void setUnmarshaller(Unmarshaller unmarshaller);
}

/**
 * Base class for JAXB2 converters
 */
abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractGenericHttpMessageConverter<T> {
    /** Set whether to process external entities */
    void setProcessExternalEntities(boolean processExternalEntities);
    /** Set whether to support DTD parsing */
    void setSupportDtd(boolean supportDtd);
}

Usage Examples:

// Configure message converters in RestTemplate
RestTemplate restTemplate = new RestTemplate();

// Add custom Jackson converter
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(objectMapper);

List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
converters.add(0, jsonConverter); // Add as first converter

// Configure form converter
FormHttpMessageConverter formConverter = new FormHttpMessageConverter();
formConverter.setCharset(StandardCharsets.UTF_8);
converters.add(formConverter);

// Use converters automatically
User user = restTemplate.getForObject("/api/users/1", User.class); // Uses JSON converter
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
form.add("username", "john");
restTemplate.postForObject("/api/login", form, String.class); // Uses form converter

Reactive HTTP Codecs

Reactive message readers and writers for non-blocking streaming applications.

/**
 * Contract to read HTTP messages reactively
 */
interface HttpMessageReader<T> {
    /** Check if this reader can read the given type and media type */
    boolean canRead(ResolvableType elementType, MediaType mediaType);
    /** Get readable media types */
    List<MediaType> getReadableMediaTypes();
    /** Get readable media types for a specific type */
    default List<MediaType> getReadableMediaTypes(ResolvableType elementType) {
        return getReadableMediaTypes();
    }
    
    /** Read object stream from reactive HTTP input */
    Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);
    /** Read single object from reactive HTTP input */
    Mono<T> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);
}

/**
 * Contract to write HTTP messages reactively
 */
interface HttpMessageWriter<T> {
    /** Check if this writer can write the given type and media type */
    boolean canWrite(ResolvableType elementType, MediaType mediaType);
    /** Get writable media types */
    List<MediaType> getWritableMediaTypes();
    /** Get writable media types for a specific type */
    default List<MediaType> getWritableMediaTypes(ResolvableType elementType) {
        return getWritableMediaTypes();
    }
    
    /** Write object stream to reactive HTTP output */
    Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType elementType, 
                    MediaType mediaType, ReactiveHttpOutputMessage message, 
                    Map<String, Object> hints);
}

Codec Configuration

Configuration interfaces for managing HTTP message readers and writers.

/**
 * Contract to configure HTTP message readers and writers
 */
interface CodecConfigurer {
    /** Configure default codecs */
    DefaultCodecs defaultCodecs();
    /** Configure custom codecs */
    CustomCodecs customCodecs();
    /** Set whether to register default codecs */
    void registerDefaults(boolean registerDefaults);
    
    /** Get configured readers */
    List<HttpMessageReader<?>> getReaders();
    /** Get configured writers */
    List<HttpMessageWriter<?>> getWriters();
    
    /** Clone this configurer */
    CodecConfigurer clone();
}

/**
 * Client-specific codec configurer
 */
interface ClientCodecConfigurer extends CodecConfigurer {
    /** Configure default codecs for client use */
    ClientDefaultCodecs defaultCodecs();
    
    interface ClientDefaultCodecs extends DefaultCodecs {
        /** Set max in-memory buffer size */
        void maxInMemorySize(int byteCount);
        /** Configure multipart codecs */
        MultipartCodecs multipartCodecs();
        /** Set enable logging request details */
        void enableLoggingRequestDetails(boolean enable);
    }
}

/**
 * Server-specific codec configurer
 */
interface ServerCodecConfigurer extends CodecConfigurer {
    /** Configure default codecs for server use */
    ServerDefaultCodecs defaultCodecs();
    
    interface ServerDefaultCodecs extends DefaultCodecs {
        /** Set max in-memory buffer size */
        void maxInMemorySize(int byteCount);
        /** Configure multipart codecs */
        MultipartCodecs multipartCodecs();
        /** Set enable logging request details */
        void enableLoggingRequestDetails(boolean enable);
    }
}

/**
 * Default codec configuration
 */
interface DefaultCodecs {
    /** Configure Jackson JSON codec */
    void jackson2JsonDecoder(Decoder<?> decoder);
    void jackson2JsonEncoder(Encoder<?> encoder);
    
    /** Configure Jackson Smile codec */
    void jackson2SmileDecoder(Decoder<?> decoder);
    void jackson2SmileEncoder(Encoder<?> encoder);
    
    /** Configure protobuf codec */
    void protobufDecoder(Decoder<?> decoder);
    void protobufEncoder(Encoder<?> encoder);
    
    /** Configure JAXB2 codec */
    void jaxb2Decoder(Decoder<?> decoder);
    void jaxb2Encoder(Encoder<?> encoder);
    
    /** Configure multipart reader */
    void multipartReader(HttpMessageReader<?> reader);
    /** Configure multipart writer */  
    void multipartWriter(HttpMessageWriter<?> writer);
}

/**
 * Custom codec configuration
 */
interface CustomCodecs {
    /** Register custom reader */
    void register(HttpMessageReader<?> reader);
    /** Register custom writer */
    void register(HttpMessageWriter<?> writer);
    
    /** Register reader with order */
    void registerWithDefaultConfig(HttpMessageReader<?> reader);
    /** Register writer with order */
    void registerWithDefaultConfig(HttpMessageWriter<?> writer);
}

Common Reactive Codec Implementations

Built-in reactive codecs for common data formats.

/**
 * Decoder-based HTTP message reader
 */
class DecoderHttpMessageReader<T> implements HttpMessageReader<T> {
    DecoderHttpMessageReader(Decoder<T> decoder);
    
    /** Get the underlying decoder */
    Decoder<T> getDecoder();
}

/**
 * Encoder-based HTTP message writer  
 */
class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
    EncoderHttpMessageWriter(Encoder<T> encoder);
    
    /** Get the underlying encoder */
    Encoder<T> getEncoder();
}

/**
 * Jackson 2 JSON encoder for reactive streams
 */
class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMessageEncoder<Object> {
    Jackson2JsonEncoder();
    Jackson2JsonEncoder(ObjectMapper mapper, MimeType... mimeTypes);
    
    /** Set streaming media types */
    void setStreamingMediaTypes(List<MediaType> mediaTypes);
}

/**
 * Jackson 2 JSON decoder for reactive streams
 */
class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMessageDecoder<Object> {
    Jackson2JsonDecoder();
    Jackson2JsonDecoder(ObjectMapper mapper, MimeType... mimeTypes);
    
    /** Set max object count in array */
    void setMaxInMemorySize(int byteCount);
}

/**
 * Form data reader for reactive streams
 */
class FormHttpMessageReader extends LoggingCodecSupport 
    implements HttpMessageReader<MultiValueMap<String, String>> {
    FormHttpMessageReader();
    
    /** Set default charset */
    void setDefaultCharset(Charset defaultCharset);
    /** Set max in-memory size */
    void setMaxInMemorySize(int byteCount);
}

/**
 * Form data writer for reactive streams
 */
class FormHttpMessageWriter extends LoggingCodecSupport 
    implements HttpMessageWriter<MultiValueMap<String, ?>> {
    FormHttpMessageWriter();
    
    /** Set default charset */
    void setDefaultCharset(Charset defaultCharset);
}

/**
 * Server-Sent Events reader
 */
class ServerSentEventHttpMessageReader implements HttpMessageReader<Object> {
    ServerSentEventHttpMessageReader();
    ServerSentEventHttpMessageReader(Decoder<?> decoder);
    
    /** Set max in-memory size */
    void setMaxInMemorySize(int byteCount);
}

/**
 * Server-Sent Events writer
 */
class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Object> {
    ServerSentEventHttpMessageWriter();
    ServerSentEventHttpMessageWriter(Encoder<?> encoder);
}

Usage Examples:

// Configure reactive codecs
WebClient webClient = WebClient.builder()
    .codecs(configurer -> {
        // Configure Jackson
        configurer.defaultCodecs().jackson2JsonDecoder(
            new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON)
        );
        
        // Add custom codec
        configurer.customCodecs().register(new MyCustomMessageReader());
        
        // Set buffer limits
        configurer.defaultCodecs().maxInMemorySize(1024 * 1024); // 1MB
    })
    .build();

// Server codec configuration
@Configuration
public class WebConfig implements WebFluxConfigurer {
    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().jackson2JsonEncoder(customJsonEncoder());
        configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024); // 2MB
    }
}

// Use codecs automatically
Mono<User> user = webClient.get()
    .uri("/api/users/1")
    .retrieve()
    .bodyToMono(User.class); // Uses JSON decoder

Flux<String> events = webClient.get()
    .uri("/api/events")
    .accept(MediaType.TEXT_EVENT_STREAM)
    .retrieve()
    .bodyToFlux(String.class); // Uses SSE reader

Multipart Support

Support for multipart message processing in both servlet and reactive environments.

/**
 * Multipart HTTP message reader
 */
class MultipartHttpMessageReader implements HttpMessageReader<MultiValueMap<String, Part>> {
    MultipartHttpMessageReader();
    MultipartHttpMessageReader(HttpMessageReader<?> partReader);
    
    /** Set max parts count */
    void setMaxParts(int maxParts);
    /** Set max disk usage per part */
    void setMaxDiskUsagePerPart(long maxDiskUsagePerPart);
    /** Set max memory per part */
    void setMaxInMemorySize(int maxInMemorySize);
    /** Set streaming media types */
    void setStreamingMediaTypes(List<MediaType> streamingMediaTypes);
}

/**
 * Multipart HTTP message writer
 */
class MultipartHttpMessageWriter implements HttpMessageWriter<MultiValueMap<String, ?>> {
    MultipartHttpMessageWriter();
    MultipartHttpMessageWriter(List<HttpMessageWriter<?>> partWriters);
    
    /** Set boundary generation strategy */
    void setBoundaryGenerator(Supplier<String> boundaryGenerator);
    /** Set multipart charset */
    void setCharset(Charset charset);
}

/**
 * Part interface for multipart content
 */
interface Part {
    /** Get part name */
    String name();
    /** Get part headers */
    HttpHeaders headers();
    /** Get part content as data buffer flux */
    Flux<DataBuffer> content();
}

/**
 * File part for multipart file uploads
 */
interface FilePart extends Part {
    /** Get original filename */
    String filename();
    /** Transfer part content to file */
    Mono<Void> transferTo(Path dest);
    /** Transfer part content to file */
    Mono<Void> transferTo(File dest);
}

/**
 * Form field part for multipart forms
 */
interface FormFieldPart extends Part {
    /** Get form field value */
    String value();
}

Usage Examples:

// Handle multipart upload in reactive controller
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<String> handleUpload(@RequestPart("file") Mono<FilePart> filePartMono) {
    return filePartMono
        .flatMap(part -> part.transferTo(Paths.get("/uploads/" + part.filename())))
        .then(Mono.just("File uploaded successfully"));
}

// Send multipart request with WebClient
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("field", "value");
parts.add("file", new FileSystemResource("/path/to/file.txt"));

Mono<String> response = webClient.post()
    .uri("/api/upload")
    .contentType(MediaType.MULTIPART_FORM_DATA)
    .body(BodyInserters.fromMultipartData(parts))
    .retrieve()
    .bodyToMono(String.class);

Exception Handling

Exception types thrown during message conversion and processing.

/**
 * Exception thrown when message conversion fails during reading
 */
class HttpMessageNotReadableException extends HttpMessageConversionException {
    HttpMessageNotReadableException(String msg);
    HttpMessageNotReadableException(String msg, Throwable cause);
    HttpMessageNotReadableException(String msg, HttpInputMessage httpInputMessage);
    HttpMessageNotReadableException(String msg, Throwable cause, HttpInputMessage httpInputMessage);
}

/**
 * Exception thrown when message conversion fails during writing
 */
class HttpMessageNotWritableException extends HttpMessageConversionException {
    HttpMessageNotWritableException(String msg);
    HttpMessageNotWritableException(String msg, Throwable cause);
}

/**
 * Base exception for message conversion issues
 */
abstract class HttpMessageConversionException extends NestedRuntimeException {
    HttpMessageConversionException(String msg);
    HttpMessageConversionException(String msg, Throwable cause);
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework--spring-web

docs

http-abstractions.md

http-clients.md

index.md

message-conversion.md

reactive-web.md

web-binding.md

web-utilities.md

tile.json