IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module “ -> 正文阅读

[Java知识库]Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module “

Caused by: org.springframework.messaging.converter.MessageConversionException: Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.ir.mq.model.message.receive.GenerateDutyMQMessage["createTime"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.ir.mq.model.message.receive.GenerateDutyMQMessage["createTime"])
	at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertToInternal(MappingJackson2MessageConverter.java:273)
	at org.springframework.messaging.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:201)
	at org.springframework.messaging.converter.CompositeMessageConverter.toMessage(CompositeMessageConverter.java:96)
	at org.springframework.messaging.core.AbstractMessageSendingTemplate.doConvert(AbstractMessageSendingTemplate.java:181)
	at org.apache.rocketmq.spring.core.RocketMQTemplate.doConvert(RocketMQTemplate.java:985)
	at org.apache.rocketmq.spring.core.RocketMQTemplate.createRocketMqMessage(RocketMQTemplate.java:1025)
	at org.apache.rocketmq.spring.core.RocketMQTemplate.sendAndReceive(RocketMQTemplate.java:238)
	... 115 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.ir.mq.model.message.receive.GenerateDutyMQMessage["createTime"])
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
	at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:3126)
	at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertToInternal(MappingJackson2MessageConverter.java:255)
	... 121 common frames omitted

springboot 对象转json报错,原因很简单jackson不支持LocalDateTime需要额外引入依赖

<dependency>
	<groupId>com.fasterxml.jackson.datatype</groupId>
	<artifactId>jackson-datatype-jsr310</artifactId>
	<version>2.13.0</version>
</dependency>

引入后依旧报错。

源码跟踪

com.fasterxml.jackson.databind.ser.BeanSerializerFactory#_findUnsupportedTypeSerializer
    protected JsonSerializer<?> _findUnsupportedTypeSerializer(SerializerProvider ctxt,
            JavaType type, BeanDescription beanDesc)
        throws JsonMappingException
    {
        // 05-May-2020, tatu: Should we check for possible Shape override to "POJO"?
        //   (to let users force 'serialize-as-POJO'?
        final String errorMsg = BeanUtil.checkUnsupportedType(type);
        if (errorMsg != null) {
            // 30-Sep-2020, tatu: [databind#2867] Avoid checks if there is a mix-in
            //    which likely providers a handler...
            if (ctxt.getConfig().findMixInClassFor(type.getRawClass()) == null) {
                return new UnsupportedTypeSerializer(type, errorMsg);
            }
        }
        return null;
    }

在BeanSerializerFactory这个类中获取JsonSerializer时会检查不支持的类。

com.fasterxml.jackson.databind.util.BeanUtil#checkUnsupportedType
   public static String checkUnsupportedType(JavaType type) {
        final String className = type.getRawClass().getName();
        String typeName, moduleName;

        if (isJava8TimeClass(className)) {
            // [modules-java8#207]: do NOT check/block helper types in sub-packages,
            // but only main-level types (to avoid issues with module)
            if (className.indexOf('.', 10) >= 0) {
                return null;
            }
            typeName =  "Java 8 date/time";
            moduleName = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310";
        } else if (isJodaTimeClass(className)) {
            typeName =  "Joda date/time";
            moduleName = "com.fasterxml.jackson.datatype:jackson-datatype-joda";
        } else {
            return null;
        }
        return String.format("%s type %s not supported by default: add Module \"%s\" to enable handling",
                typeName, ClassUtil.getTypeDescription(type), moduleName);
    }

从源码上面看Java8的date/time和joda的date/time是不支持的。

回到com.fasterxml.jackson.databind.ser.BeanSerializerFactory#_findUnsupportedTypeSerializer方法中,如果存在错误errorMsg,则会去SerializerProvider类的SerializationConfig配置中寻找_mixIns

。。。。。后面就不知道怎么玩了。手动哭笑

然后继续百度,在GitHub的问题中找到了思路。

Springboot 2.5.0 - Regression - Swagger3 RuntimeException: Could not write JSON · Issue #3829 · springfox/springfox · GitHub

其中有这句话Tried opening a SpringBoot issue, but it seems this is internal springfox issue, as explained to me here:

然后想到我其他实体类中的LocalDateTime是能正常转换的。于是开始看rocketMQ的json配置源码,

@Configuration
@ConditionalOnMissingBean(RocketMQMessageConverter.class)
class MessageConverterConfiguration {

    @Bean
    public RocketMQMessageConverter createRocketMQMessageConverter() {
        return new RocketMQMessageConverter();
    }

}


public RocketMQMessageConverter() {
        List<MessageConverter> messageConverters = new ArrayList<>();
        ByteArrayMessageConverter byteArrayMessageConverter = new ByteArrayMessageConverter();
        byteArrayMessageConverter.setContentTypeResolver(null);
        messageConverters.add(byteArrayMessageConverter);
        messageConverters.add(new StringMessageConverter());
        if (JACKSON_PRESENT) {
            messageConverters.add(new MappingJackson2MessageConverter());
        }
        if (FASTJSON_PRESENT) {
            try {
                messageConverters.add(
                    (MessageConverter)ClassUtils.forName(
                        "com.alibaba.fastjson.support.spring.messaging.MappingFastJsonMessageConverter",
                        ClassUtils.getDefaultClassLoader()).newInstance());
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException ignored) {
                //ignore this exception
            }
        }
        messageConverter = new CompositeMessageConverter(messageConverters);
    }

从源码来看支持四种convert分别是字节、String、JackSon、fastJson。

org.springframework.messaging.converter.AbstractMessageConverter#toMessage(java.lang.Object, org.springframework.messaging.MessageHeaders, java.lang.Object)

public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
		if (!canConvertTo(payload, headers)) {
			return null;
		}

		Object payloadToUse = convertToInternal(payload, headers, conversionHint);
		if (payloadToUse == null) {
			return null;
		}

		MimeType mimeType = getDefaultContentType(payloadToUse);
		if (headers != null) {
			MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class);
			if (accessor != null && accessor.isMutable()) {
				if (mimeType != null) {
					accessor.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType);
				}
				return MessageBuilder.createMessage(payloadToUse, accessor.getMessageHeaders());
			}
		}

		MessageBuilder<?> builder = MessageBuilder.withPayload(payloadToUse);
		if (headers != null) {
			builder.copyHeaders(headers);
		}
		if (mimeType != null) {
			builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType);
		}
		return builder.build();
	}

// 只有jackson和fastjson才能canConvertTo,由于jackson的顺序在前面,就优先走了jackson

猜测,rocketMQ的MappingJackson2MessageConverter的objectMapper与springboot默认的不是一个对象,而rocketMQ的没有注册JavaTimeModule。

重写rocketMQ的json配置试一下

@Configuration
public class RocketConfig
{
    @Bean
    public RocketMQMessageConverter createRocketMQMessageConverter() {
        RocketMQMessageConverter converter = new RocketMQMessageConverter();
        CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
        List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
        /*for (int i = 0; i < messageConverterList.size(); i++)
        {
            // rocketMQ SpringBoot jackson转换LocalDate报错 暂时使用fastJson
            if (messageConverterList.get(i) instanceof MappingJackson2MessageConverter) {
                messageConverterList.remove(messageConverterList.get(i));
                i = i - 1;
            }
        }*/
        for (MessageConverter messageConverter : messageConverterList)
        {
            if (messageConverter instanceof MappingJackson2MessageConverter) {
                MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
                ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
                objectMapper.registerModules(new JavaTimeModule());
            }
        }
        return converter;
    }
}

启动重试,哈哈不报错了,暂时先这么玩吧

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:07:02  更:2021-12-06 15:08:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:04:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码