Skip to content

Commit

Permalink
Fix bug where type binding generic fields are not properly serialized
Browse files Browse the repository at this point in the history
  • Loading branch information
rowstop authored and wenshao committed Jun 4, 2024
1 parent d3fac36 commit 5db0aee
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ protected void acceptAny(T object, Object fieldValue, long features) {
String fieldValueJson = JSON.toJSONString(fieldValue);
typedFieldValue = initReader.readObject(JSONReader.of(fieldValueJson), fieldType, fieldName, features);
} else {
typedFieldValue = TypeUtils.cast(fieldValue, fieldClass, provider);
typedFieldValue = TypeUtils.cast(fieldValue, fieldType, provider);
}
} else {
if (autoCast) {
Expand Down
116 changes: 113 additions & 3 deletions core/src/test/java/com/alibaba/fastjson2/reader/FieldReaderTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package com.alibaba.fastjson2.reader;

import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.*;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -222,4 +229,107 @@ public void setValues(List<Long> values) {
this.values = values;
}
}

@Test
public void testRangeTemporal() {
ObjectReader<RangeDateTime> objectReader = ObjectReaders.of(
RangeDateTime.class,
RangeDateTime::new,
ObjectReaders.fieldReader(
"start",
LocalDateTime.class,
Temporal.class,
(AbstractRangeTemporal value, Temporal start) -> value.setStart(start)
)
);
FieldReader start = objectReader.getFieldReader("start");
RangeDateTime rangeDateTime = new RangeDateTime();
LocalDateTime startTime = LocalDateTime.now();
Assertions.assertDoesNotThrow(() -> start.acceptAny(rangeDateTime, startTime.toString(), 0));
Assertions.assertEquals(startTime, rangeDateTime.start);
}
public static class RangeDateTime
extends AbstractRangeTemporal<RangeDateTime, LocalDateTime> {
}
/**
* @author 张治保
* @since 2024/5/30
*/
@Getter
@ToString
@EqualsAndHashCode
public abstract static class AbstractRangeTemporal<S extends AbstractRangeTemporal<S, T>, T extends Temporal>
implements Serializable {
/**
* 开始时间
*/
protected T start;

/**
* 结束时间
*/
protected T end;

@SuppressWarnings("unchecked")
public final S setStart(T start) {
validateIt(start, end);
this.start = start;
return (S) this;
}

@SuppressWarnings("unchecked")
public final S setEnd(T end) {
validateIt(start, end);
this.end = end;
return (S) this;
}

/**
* 开始时间结束时间转换成时间段
*
* @return 时间段
*/
public final Duration toDuration() {
if (start == null || end == null) {
return null;
}
return Duration.between(start, end);
}

/**
* 验证时间范围 设置是否正确
*
* @param start 开始时间
* @param end 结束时间
*/
private void validateIt(T start, T end) {
if (start == null || end == null) {
return;
}
if (isAfter(start, end)) {
throw new TimeRangeException();
}
}

/**
* 判断开始时间是否在结束时间之后
*
* @param start 开始时间
* @param end 结束时间
* @return 是否在结束时间之后
*/
protected final boolean isAfter(@NonNull T start, @NonNull T end) {
return Duration.between(start, end).isNegative();
}

/**
* 时间范围异常
*/
public static final class TimeRangeException
extends RuntimeException {
public TimeRangeException() {
super("start time cannot be greater than end time");
}
}
}
}

0 comments on commit 5db0aee

Please sign in to comment.