Spring MessageConverter

  • Author: HuiFer
  • 源码阅读仓库: SourceHot-spring
  • 源码路径: org.springframework.messaging.converter.MessageConverter

MessageConverter

  • 消息转换接口
  • 类图如下 image-20200305085013723
  • 两个方法
  1. fromMessage: 从消息转换到 Object
  1. Object fromMessage(Message<?> message, Class<?> targetClass);
  1. toMessage: 从 Object 转换到消息
  1. Message<?> toMessage(Object payload, @Nullable MessageHeaders headers);
序号 class 作用
1 ByteArrayMessageConverter byte 数组消息转换器
2 MappingJackson2MessageConverter jackson2 的消息转换器
3 MarshallingMessageConverter xml 的消息转换器
4 StringMessageConverter 字符串消息转换器

AbstractMessageConverter

类图:

image-20200305085845017

fromMessage

  1. @Override
  2. @Nullable
  3. public final Object fromMessage(Message<?> message, Class<?> targetClass) {
  4. return fromMessage(message, targetClass, null);
  5. }
  6. @Override
  7. @Nullable
  8. public final Object fromMessage(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
  9. if (!canConvertFrom(message, targetClass)) {
  10. return null;
  11. }
  12. return convertFromInternal(message, targetClass, conversionHint);
  13. }
  14. // 子类实现
  15. @Nullable
  16. protected Object convertFromInternal(
  17. Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
  18. return null;
  19. }
  • 真正的转换过程
  1. @Override
  2. protected Object convertFromInternal(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
  3. Charset charset = getContentTypeCharset(getMimeType(message.getHeaders()));
  4. Object payload = message.getPayload();
  5. return (payload instanceof String ? payload : new String((byte[]) payload, charset));
  6. }

toMessage

  1. @Override
  2. @Nullable
  3. public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) {
  4. return toMessage(payload, headers, null);
  5. }
  1. @Override
  2. @Nullable
  3. public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
  4. if (!canConvertTo(payload, headers)) {
  5. return null;
  6. }
  7. // 子类实现
  8. Object payloadToUse = convertToInternal(payload, headers, conversionHint);
  9. if (payloadToUse == null) {
  10. return null;
  11. }
  12. MimeType mimeType = getDefaultContentType(payloadToUse);
  13. if (headers != null) {
  14. MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class);
  15. if (accessor != null && accessor.isMutable()) {
  16. if (mimeType != null) {
  17. accessor.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType);
  18. }
  19. // 创建信息对象
  20. return MessageBuilder.createMessage(payloadToUse, accessor.getMessageHeaders());
  21. }
  22. }
  23. MessageBuilder<?> builder = MessageBuilder.withPayload(payloadToUse);
  24. if (headers != null) {
  25. builder.copyHeaders(headers);
  26. }
  27. if (mimeType != null) {
  28. builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType);
  29. }
  30. return builder.build();
  31. }
  • org.springframework.messaging.converter.StringMessageConverter#convertToInternal

    1. @Override
    2. @Nullable
    3. protected Object convertToInternal(
    4. Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
    5. if (byte[].class == getSerializedPayloadClass()) {
    6. // 获取编码
    7. Charset charset = getContentTypeCharset(getMimeType(headers));
    8. // 获取byte数组
    9. payload = ((String) payload).getBytes(charset);
    10. }
    11. return payload;
    12. }
  • 创建Message对象

    1. @SuppressWarnings("unchecked")
    2. public static <T> Message<T> createMessage(@Nullable T payload, MessageHeaders messageHeaders) {
    3. Assert.notNull(payload, "Payload must not be null");
    4. Assert.notNull(messageHeaders, "MessageHeaders must not be null");
    5. if (payload instanceof Throwable) {
    6. return (Message<T>) new ErrorMessage((Throwable) payload, messageHeaders);
    7. }
    8. else {
    9. return new GenericMessage<>(payload, messageHeaders);
    10. }
    11. }
    1. @SuppressWarnings("unchecked")
    2. public Message<T> build() {
    3. if (this.originalMessage != null && !this.headerAccessor.isModified()) {
    4. return this.originalMessage;
    5. }
    6. MessageHeaders headersToUse = this.headerAccessor.toMessageHeaders();
    7. if (this.payload instanceof Throwable) {
    8. return (Message<T>) new ErrorMessage((Throwable) this.payload, headersToUse);
    9. }
    10. else {
    11. return new GenericMessage<>(this.payload, headersToUse);
    12. }
    13. }
  • 两种创建方式基本相同,如果出现异常组装异常消息对象ErrorMessage,成功创建GenericMessage

image-20200305090846313

从类图上看ErrorMessageGenericMessage的子类