SpringMvc源码阅读

HTTP消息转换

使用HttpMessageConverter将HTTP请求体转换为对应的Java对象。 使用WebDataBinder机制转换HTTP请求参数并且提供验证功能。(通过Converter,Formatter,GenericConverter三个接口进行各类参数转换。这三种接口实例的注册和管理,通过ConversionService接口的默认子类DefaultFormattingConversionService的实例来管理)

HTTP请求体的转换

使用HttpMessageConverter将HTTP请求体转换为对应的Java对象。以及对象到HTTP响应体的转换。

package org.springframework.http.converter;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;

/**
 * Strategy interface for converting from and to HTTP requests and responses.
 */
public interface HttpMessageConverter<T> {

    /**
     * Indicates whether the given class can be read by this converter.
     * @param clazz the class to test for readability
     * @param mediaType the media type to read (can be {@code null} if not specified);
     * typically the value of a {@code Content-Type} header.
     * @return {@code true} if readable; {@code false} otherwise
     */
    boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

    /**
     * Indicates whether the given class can be written by this converter.
     * @param clazz the class to test for writability
     * @param mediaType the media type to write (can be {@code null} if not specified);
     * typically the value of an {@code Accept} header.
     * @return {@code true} if writable; {@code false} otherwise
     */
    boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

    /**
     * Return the list of media types supported by this converter. The list may
     * not apply to every possible target element type and calls to this method
     * should typically be guarded via {@link #canWrite(Class, MediaType)
     * canWrite(clazz, null}. The list may also exclude MIME types supported
     * only for a specific class. Alternatively, use
     * {@link #getSupportedMediaTypes(Class)} for a more precise list.
     * @return the list of supported media types
     */
    List<MediaType> getSupportedMediaTypes();

    /**
     * Return the list of media types supported by this converter for the given
     * class. The list may differ from {@link #getSupportedMediaTypes()} if the
     * converter does not support the given Class or if it supports it only for
     * a subset of media types.
     * @param clazz the type of class to check
     * @return the list of media types supported for the given class
     * @since 5.3.4
     */
    default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
        return (canRead(clazz, null) || canWrite(clazz, null) ?
                getSupportedMediaTypes() : Collections.emptyList());
    }

    /**
     * Read an object of the given type from the given input message, and returns it.
     * @param clazz the type of object to return. This type must have previously been passed to the
     * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
     * @param inputMessage the HTTP input message to read from
     * @return the converted object
     * @throws IOException in case of I/O errors
     * @throws HttpMessageNotReadableException in case of conversion errors
     */
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
            throws IOException, HttpMessageNotReadableException;

    /**
     * Write a given object to the given output message.
     * @param t the object to write to the output message. The type of this object must have previously been
     * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
     * @param contentType the content type to use when writing. May be {@code null} to indicate that the
     * default content type of the converter must be used. If not {@code null}, this media type must have
     * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
     * returned {@code true}.
     * @param outputMessage the message to write to
     * @throws IOException in case of I/O errors
     * @throws HttpMessageNotWritableException in case of conversion errors
     */
    void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException;

}

主要就是canRead,canWrite, read, write 四个方法。 是否能读对应的MediaType类型,读为对应的Java类。 读为Java对象。 是否能写为对应的MediaType, 写为MediaType。

MediaType extends MimeType,主要是一些常量定义。主要对应 HTTP请求与响应头的 Content-Type,Accept 两个字段。

HttpInputMessage是HTTP请求的包装, HttpOutPutMessage是HTTP响应的包装。

package org.springframework.http;

import java.io.IOException;
import java.io.InputStream;

/**
 * Represents an HTTP input message, consisting of {@linkplain #getHeaders() headers}
 * and a readable {@linkplain #getBody() body}.
 *
 * <p>Typically implemented by an HTTP request handle on the server side,
 * or an HTTP response handle on the client side.
 *
 * @author Arjen Poutsma
 * @since 3.0
 */
public interface HttpInputMessage extends HttpMessage {

    /**
     * Return the body of the message as an input stream.
     * @return the input stream body (never {@code null})
     * @throws IOException in case of I/O errors
     */
    InputStream getBody() throws IOException;

}
package org.springframework.http;

/**
 * Represents the base interface for HTTP request and response messages.
 * Consists of {@link HttpHeaders}, retrievable via {@link #getHeaders()}.
 *
 * @author Arjen Poutsma
 * @since 3.0
 */
public interface HttpMessage {

    /**
     * Return the headers of this message.
     * @return a corresponding HttpHeaders object (never {@code null})
     */
    HttpHeaders getHeaders();

}
package org.springframework.http;

import java.io.IOException;
import java.io.OutputStream;

/**
 * Represents an HTTP output message, consisting of {@linkplain #getHeaders() headers}
 * and a writable {@linkplain #getBody() body}.
 *
 * <p>Typically implemented by an HTTP request handle on the client side,
 * or an HTTP response handle on the server side.
 *
 * @author Arjen Poutsma
 * @since 3.0
 */
public interface HttpOutputMessage extends HttpMessage {

    /**
     * Return the body of the message as an output stream.
     * @return the output stream body (never {@code null})
     * @throws IOException in case of I/O errors
     */
    OutputStream getBody() throws IOException;

}

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注