-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
When json is deserialized, the JsonDeserializer returned in the custom ContextualDeserializer is not executed. #2978
Comments
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
The text was updated successfully, but these errors were encountered: