-
Notifications
You must be signed in to change notification settings - Fork 479
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support jackson annotation JsonTypeInfo on interface, for issue #2548
- Loading branch information
Showing
2 changed files
with
267 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
249 changes: 249 additions & 0 deletions
249
core/src/test/java/com/alibaba/fastjson2/issues_2500/Issue2548A.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
package com.alibaba.fastjson2.issues_2500; | ||
|
||
import com.alibaba.fastjson2.JSON; | ||
import com.alibaba.fastjson2.JSONWriter; | ||
import com.fasterxml.jackson.annotation.*; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.Serializable; | ||
import java.math.BigDecimal; | ||
import java.util.Objects; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
public class Issue2548A { | ||
@Test | ||
public void fastJson() { | ||
StoreDTO storeDTO = new StoreDTO(); | ||
BananaDTO banana = new BananaDTO(); | ||
banana.setCount(BigDecimal.valueOf(10)); | ||
storeDTO.setItem(banana); | ||
|
||
String jsonString = JSON.toJSONString(storeDTO, JSONWriter.Feature.WriteNulls); | ||
assertEquals("{\"item\":{\"kind\":\"banana\",\"count\":10},\"storeId\":null}", jsonString); | ||
|
||
StoreDTO store = JSON.parseObject(jsonString, StoreDTO.class); | ||
|
||
assertEquals("banana", store.getItem().getKind()); | ||
} | ||
|
||
@Test | ||
public void jackson() throws Exception { | ||
//given | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
StoreDTO storeDTO = new StoreDTO(); | ||
BananaDTO banana = new BananaDTO(); | ||
banana.setCount(BigDecimal.valueOf(10)); | ||
storeDTO.setItem(banana); | ||
|
||
//when | ||
String jsonString = objectMapper.writeValueAsString(storeDTO); | ||
StoreDTO store = objectMapper.readValue(jsonString, StoreDTO.class); | ||
|
||
//then | ||
assertEquals("banana", store.getItem().getKind()); | ||
} | ||
|
||
@JsonTypeName("store") | ||
public static class StoreDTO | ||
implements Serializable { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private String storeId; | ||
|
||
private FruitDTO item; | ||
|
||
public StoreDTO storeId(String storeId) { | ||
this.storeId = storeId; | ||
return this; | ||
} | ||
|
||
/** | ||
* The unique ID of the fruit | ||
* @return storeId | ||
*/ | ||
|
||
@JsonProperty("storeId") | ||
public String getStoreId() { | ||
return storeId; | ||
} | ||
|
||
public void setStoreId(String storeId) { | ||
this.storeId = storeId; | ||
} | ||
|
||
public StoreDTO item(FruitDTO item) { | ||
this.item = item; | ||
return this; | ||
} | ||
|
||
/** | ||
* Get item | ||
* @return item | ||
*/ | ||
@JsonProperty("item") | ||
public FruitDTO getItem() { | ||
return item; | ||
} | ||
|
||
public void setItem(FruitDTO item) { | ||
this.item = item; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
StoreDTO store = (StoreDTO) o; | ||
return Objects.equals(this.storeId, store.storeId) && | ||
Objects.equals(this.item, store.item); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(storeId, item); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append("class StoreDTO {\n"); | ||
sb.append(" storeId: ").append(toIndentedString(storeId)).append("\n"); | ||
sb.append(" item: ").append(toIndentedString(item)).append("\n"); | ||
sb.append("}"); | ||
return sb.toString(); | ||
} | ||
|
||
/** | ||
* Convert the given object to string with each line indented by 4 spaces | ||
* (except the first line). | ||
*/ | ||
private String toIndentedString(Object o) { | ||
if (o == null) { | ||
return "null"; | ||
} | ||
return o.toString().replace("\n", "\n "); | ||
} | ||
} | ||
|
||
@JsonIgnoreProperties( | ||
value = "kind", // ignore manually set kind, it will be automatically generated by Jackson during serialization | ||
allowSetters = true // allows the kind to be set during deserialization | ||
) | ||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "kind", visible = true) | ||
@JsonSubTypes({ | ||
@JsonSubTypes.Type(value = AppleDTO.class, name = "apple"), | ||
@JsonSubTypes.Type(value = BananaDTO.class, name = "banana") | ||
}) | ||
public interface FruitDTO | ||
extends Serializable { | ||
public String getKind(); | ||
} | ||
|
||
@JsonTypeName("banana") | ||
public static class BananaDTO | ||
implements Serializable, FruitDTO { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private String kind; | ||
|
||
private BigDecimal count; | ||
|
||
public BananaDTO kind(String kind) { | ||
this.kind = kind; | ||
return this; | ||
} | ||
|
||
/** | ||
* Get kind | ||
* @return kind | ||
*/ | ||
|
||
@JsonProperty("kind") | ||
public String getKind() { | ||
return kind; | ||
} | ||
|
||
public void setKind(String kind) { | ||
this.kind = kind; | ||
} | ||
|
||
public BananaDTO count(BigDecimal count) { | ||
this.count = count; | ||
return this; | ||
} | ||
|
||
/** | ||
* Get count | ||
* @return count | ||
*/ | ||
@JsonProperty("count") | ||
public BigDecimal getCount() { | ||
return count; | ||
} | ||
|
||
public void setCount(BigDecimal count) { | ||
this.count = count; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
BananaDTO banana = (BananaDTO) o; | ||
return Objects.equals(this.kind, banana.kind) && | ||
Objects.equals(this.count, banana.count); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(kind, count); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append("class BananaDTO {\n"); | ||
sb.append(" kind: ").append(toIndentedString(kind)).append("\n"); | ||
sb.append(" count: ").append(toIndentedString(count)).append("\n"); | ||
sb.append("}"); | ||
return sb.toString(); | ||
} | ||
|
||
/** | ||
* Convert the given object to string with each line indented by 4 spaces | ||
* (except the first line). | ||
*/ | ||
private String toIndentedString(Object o) { | ||
if (o == null) { | ||
return "null"; | ||
} | ||
return o.toString().replace("\n", "\n "); | ||
} | ||
} | ||
|
||
@JsonTypeName("apple") | ||
public static class AppleDTO | ||
implements Serializable, FruitDTO { | ||
private String kind; | ||
|
||
@Override | ||
public String getKind() { | ||
return kind; | ||
} | ||
|
||
public void setKind(String kind) { | ||
this.kind = kind; | ||
} | ||
} | ||
} |