Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 531 #534

Merged
merged 3 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,34 @@

package org.dromara.dynamictp.common.parser.json;

import lombok.extern.slf4j.Slf4j;

/**
*
* @author topsuder
* @since 1.1.3
*/
@Slf4j
public abstract class AbstractJsonParser implements JsonParser {

@Override
public boolean supports() {
try {
Class.forName(getMapperClassName());
return true;
} catch (ClassNotFoundException e) {
return false;
String[] mapperClassNames = getMapperClassNames();
for (String mapperClassName : mapperClassNames) {
try {
Class.forName(mapperClassName);
} catch (ClassNotFoundException e) {
log.warn("the current parser is {}, Can not find class: {}", this.getClass().getSimpleName(), mapperClassName);
return false;
}
}
return true;
}

/**
* get mapper class name
*
* @return mapper class name
*/
protected abstract String getMapperClassName();
protected abstract String[] getMapperClassNames();
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public String toJson(Object obj) {
}

@Override
protected String getMapperClassName() {
return PACKAGE_NAME;
protected String[] getMapperClassNames() {
return new String[]{PACKAGE_NAME};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public LocalDateTime read(JsonReader in) throws IOException {
}

@Override
protected String getMapperClassName() {
return PACKAGE_NAME;
protected String[] getMapperClassNames() {
return new String[]{PACKAGE_NAME};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.dynamictp.common.parser.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* @author <a href = "mailto:[email protected]">KamTo Hung</a>
*/
public class JacksonCreator {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果不引入jackson-datatype-jsr310,通过SPI获取JacksonParser的时候会异常(找不到com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer),所以创建一个JacksonCreator


private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

protected static ObjectMapper createMapper() {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_FORMAT)));
return JsonMapper.builder()
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
// 反序列化时,遇到未知属性会不会报错 true - 遇到没有的属性就报错 false - 没有的属性不会管,不会报错
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// 如果是空对象的时候,不抛异常
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
// 序列化的时候序列对象的那些属性
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
.addModules(javaTimeModule)
.addModules(new JavaTimeModule())
// 修改序列化后日期格式
.defaultDateFormat(new SimpleDateFormat(DATE_FORMAT))
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,24 @@

package org.dromara.dynamictp.common.parser.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
*
* @author topsuder
* @since 1.1.3
*/
@Slf4j
public class JacksonParser extends AbstractJsonParser {

private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String PACKAGE_NAME = "com.fasterxml.jackson.databind.ObjectMapper";

private static final String JAVA_TIME_MODULE_CLASS_NAME = "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule";

private volatile ObjectMapper mapper;

@Override
Expand Down Expand Up @@ -79,27 +69,11 @@ private ObjectMapper getMapper() {
}

protected ObjectMapper createMapper() {
// 只提供最简单的方案
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return JsonMapper.builder()
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
// 反序列化时,遇到未知属性会不会报错 true - 遇到没有的属性就报错 false - 没有的属性不会管,不会报错
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// 如果是空对象的时候,不抛异常
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
// 序列化的时候序列对象的那些属性
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
.addModules(javaTimeModule)
.addModules(new JavaTimeModule())
// 修改序列化后日期格式
.defaultDateFormat(new SimpleDateFormat(DATE_FORMAT))
.build();
return JacksonCreator.createMapper();
}

@Override
protected String getMapperClassName() {
return PACKAGE_NAME;
protected String[] getMapperClassNames() {
return new String[]{PACKAGE_NAME, JAVA_TIME_MODULE_CLASS_NAME};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ private static JsonParser createJsonParser() {
try {
JsonParser jsonParser = iterator.next();
if (jsonParser.supports()) {
log.info("Using JSON parser: {}", jsonParser.getClass().getName());
return jsonParser;
}
} catch (Throwable ignored) {
} catch (Throwable e) {
log.error("Failed to load JSON parser", e);
}
}
throw new IllegalStateException("No JSON parser found");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ dynamictp:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
notifyItems: # 报警项,不配置自动会按默认值配置(变更通知、容量报警、活性报警、拒绝报警、任务超时报警)
- type: capacity # 报警项类型,查看源码 NotifyTypeEnum枚举类
enabled: true
Expand Down