Open LkZtCode opened 3 months ago
If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
this my custom @interface
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.trustasia.cloudpki.common.base.core.localizedtime.jsonformat.deserialize.LocalizedJsonFormatDeserialize;
import com.trustasia.cloudpki.common.base.core.localizedtime.jsonformat.serialize.LocalizedJsonFormatSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = LocalizedJsonFormatSerialize.class)
@JsonDeserialize(using = LocalizedJsonFormatDeserialize.class)
public @interface LocalizedJsonFormat {
String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
String pattern() default DEFAULT_PATTERN;
}
this is custom JsonDeserializer
@Slf4j
public class LocalizedDateDeserialize extends JsonDeserializer<Date> {
private String pattern;
private ZoneId defaultZoneid = ZoneId.systemDefault();
private SimpleDateFormat defaultSimpleDateFormat;
private CommonSecurity commonSecurity;
public LocalizedDateDeserialize(String pattern) {
this.pattern = pattern;
this.defaultSimpleDateFormat = new SimpleDateFormat(pattern);
this.commonSecurity = SpringUtils.getBean(CommonSecurity.class);
}
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
String dateStr = jsonParser.getText().trim();
if (StringUtils.isBlank(dateStr)) {
return null;
}
// 尝试获取时区ID,若无则使用默认处理逻辑
ZoneId targetZoneId = commonSecurity.getCurrentTimeZoneId()
.or(() -> Optional.of(defaultZoneid.getId()))
.map(ZoneId::of)
.orElseGet(() -> defaultZoneid);
if (defaultZoneid.equals(targetZoneId)) {
return generateDefaultDate(dateStr);
}
EnhanceSimpleDateFormat enhanceSimpleDateFormat = new EnhanceSimpleDateFormat(this.pattern, targetZoneId);
try {
return enhanceSimpleDateFormat.parse(dateStr);
} catch (ParseException e) {
log.error("LocalizedDateDeserialize parse Date error", e);
throw new LocalizedJsonFormatException(String.format("Failed to parse Date value '%s'", dateStr));
}
}
private Date generateDefaultDate(String dateStr) {
try {
return defaultSimpleDateFormat.parse(dateStr);
} catch (ParseException e) {
log.error("LocalizedDateDeserialize parse Date error", e);
throw new LocalizedJsonFormatException(String.format("Failed to parse Date value '%s'", dateStr));
}
}
}
@NoArgsConstructor
@Slf4j
public class LocalizedJsonFormatDeserialize extends JsonDeserializer<Object> implements ContextualDeserializer {
@Override
public Object deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException, JacksonException {
throw new LocalizedJsonFormatException("this is proxy deserializer,not support deserialize");
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
if (beanProperty != null) {
if (Objects.equals(beanProperty.getType().getRawClass(), Date.class)) {
LocalizedJsonFormat localizedJsonFormat = beanProperty.getAnnotation(LocalizedJsonFormat.class);
if (localizedJsonFormat == null) {
localizedJsonFormat = beanProperty.getContextAnnotation(LocalizedJsonFormat.class);
}
if (localizedJsonFormat != null) {
return new LocalizedDateDeserialize(localizedJsonFormat.pattern());
}
}
return deserializationContext.findContextualValueDeserializer(beanProperty.getType(), beanProperty);
}
return deserializationContext.findNonContextualValueDeserializer(null);
}
}
in entity used @LocalizedJsonFormat
@Getter
@Setter
public class OpenApiBaseDomain implements Serializable {
public Long id;
/**
* 创建时间
*/
@LocalizedJsonFormat
private Date createAt;
/**
* 更新时间
*/
@LocalizedJsonFormat
private Date updateAt;
private Boolean deleted;
/**
* 版本号
*/
private Long version;
}
In the mvc framework, @LocalizedJsonFormat will follow custom logic, but in redis deserialization, @LocalizedJsonFor will not follow custom logic.
I added the relevant logic of custom annotations to the createContextual of DateBasedDeserializer. Redis will use the custom logic when serializing.
So I think that the logic of custom JsonDeserializer is implemented during the deserialization calling process of redis.
this is my custom ContextualDeserializer