在本文中,您将会了解到关于Jackson用spring接口列表反序列化对象的新资讯,同时我们还将为您解释springbootjackson反序列化的相关在本文中,我们将带你探索Jackson用spri
在本文中,您将会了解到关于Jackson用spring接口列表反序列化对象的新资讯,同时我们还将为您解释springboot jackson反序列化的相关在本文中,我们将带你探索Jackson用spring接口列表反序列化对象的奥秘,分析springboot jackson反序列化的特点,并给出一些关于Jackson 与Spring MVC复制嵌套对象不反序列化、Jackson-将内部对象列表反序列化为更高级别的列表、Jackson-将对象内部列表反序列化为更高级别的列表、jackson2.1.4 序列化对象时,为NULL的属性不序列化的实用技巧。
本文目录一览:- Jackson用spring接口列表反序列化对象(springboot jackson反序列化)
- Jackson 与Spring MVC复制嵌套对象不反序列化
- Jackson-将内部对象列表反序列化为更高级别的列表
- Jackson-将对象内部列表反序列化为更高级别的列表
- jackson2.1.4 序列化对象时,为NULL的属性不序列化
Jackson用spring接口列表反序列化对象(springboot jackson反序列化)
我需要从redis保存和加载对象。
该对象包含GrantedAuthority列表(除其他外),它是一个接口:
public class UserAccountAuthentication implements Authentication { private List<GrantedAuthority> authorities; private boolean authenticated = true; ...}
Jackson成功地序列化了该对象,但是未能反序列化该对象,但有以下例外:
abstract types can only be instantiated with additional type information
我知道可以通过添加以下内容来指定类型:
@JsonTypeInfo(
但是在这种情况下我无法做到这一点,因为the GrantedAuthority
是Spring的接口,我无法更改它。
序列化的json是:
{"authorities": [ { "authority": "ROLE_NORMAL_USER" }],"authenticated": true,"securityToken": { "expiration": 1458635906853, "token": "sxKi3Pddfewl2rgpatVE7KiSR5qGmhpGl0spiHUTLAAW8zuoLFE0VLFYcfk72VLnli66fcVmb8aK9qFavyix3bOwgp1DRGtGacPI", "roles": [ "ROLE_NORMAL_USER" ], "expired": false, "expirationDateFormatted": "2016-03-22 08:38:26.853 UTC"},"name": "admin","expired": false
}
摘要GrantedAuthority
只能用填充SimpleGrantedAuthority
。
所以我尝试了:
objectMapper.registerSubtypes(SimpleGrantedAuthority.class);
仍然没有运气。
答案1
小编典典我认为您需要添加自定义解串器
public class UserAccountAuthenticationSerializer extends JsonDeserializer<UserAccountAuthentication> {@Overridepublic UserAccountAuthentication deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { UserAccountAuthentication userAccountAuthentication = new UserAccountAuthentication(); ObjectCodec oc = jsonParser.getCodec(); JsonNode node = oc.readTree(jsonParser); userAccountAuthentication.setAuthenticated(node.get("authenticated").booleanValue()); Iterator<JsonNode> elements = node.get("authorities").elements(); while (elements.hasNext()) { JsonNode next = elements.next(); JsonNode authority = next.get("authority"); userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority(authority.asText())); } return userAccountAuthentication;}
}
这是我的json
{"authenticated":true,"authorities":[{"authority":"role1"},{"authority":"role2"}],"details":null,"principal":null,"credentials":null,"name":null}
然后在您的POJO顶部
@JsonDeserialize(using = UserAccountAuthenticationSerializer.class)public class UserAccountAuthentication implements Authentication {
这是测试
@Testpublic void test1() throws IOException {UserAccountAuthentication userAccountAuthentication = new UserAccountAuthentication();userAccountAuthentication.setAuthenticated(true);userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority("role1"));userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority("role2"));String json1 = new ObjectMapper().writeValueAsString(userAccountAuthentication);UserAccountAuthentication readValue = new ObjectMapper().readValue(json1, UserAccountAuthentication.class);String json2 = new ObjectMapper().writeValueAsString(readValue);assertEquals(json1, json2);
}
Jackson 与Spring MVC复制嵌套对象不反序列化
我正在尝试将以下POJO转换为JSON @RestController
:
@Entity@Table(name="user_location")@NamedQuery(name="UserLocation.findAll", query="SELECT u FROM UserLocation u")public class UserLocation implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; private String addr1; private String addr2; private String landmark; private BigDecimal lat; private BigDecimal lng; private String zipcode; //bi-directional many-to-one association to City @ManyToOne private City city; //bi-directional many-to-one association to State @ManyToOne private State state; public UserLocation() { } //Getter - Setters}
嵌套的City.java如下:
@Entity@NamedQuery(name="City.findAll", query="SELECT c FROM City c")@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = City.class)public class City implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; private String name; //bi-directional many-to-one association to State @ManyToOne @JsonIgnore private State state; //bi-directional many-to-one association to UserLocation @OneToMany(mappedBy="city") @JsonIgnore private List<UserLocation> userLocations; public City() { } public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } @JsonProperty("state") public State getState() { return this.state; } public void setState(State state) { this.state = state; } public List<UserLocation> getUserLocations() { return this.userLocations; } public void setUserLocations(List<UserLocation> userLocations) { this.userLocations = userLocations; } public UserLocation addUserLocation(UserLocation userLocation) { getUserLocations().add(userLocation); userLocation.setCity(this); return userLocation; } public UserLocation removeUserLocation(UserLocation userLocation) { getUserLocations().remove(userLocation); userLocation.setCity(null); return userLocation; }}
另一个嵌套类State.java如下:
@Entity@NamedQuery(name="State.findAll", query="SELECT s FROM State s")@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = State.class)public class State implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; private String name; //bi-directional many-to-one association to City @OneToMany(mappedBy="state") @JsonIgnore private List<City> cities; //bi-directional many-to-one association to UserLocation @OneToMany(mappedBy="state") @JsonIgnore private List<UserLocation> userLocations; public State() { } public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public List<City> getCities() { return this.cities; } public void setCities(List<City> cities) { this.cities = cities; } public City addCity(City city) { getCities().add(city); city.setState(this); return city; } public City removeCity(City city) { getCities().remove(city); city.setState(null); return city; } public List<UserLocation> getUserLocations() { return this.userLocations; } public void setUserLocations(List<UserLocation> userLocations) { this.userLocations = userLocations; } public UserLocation addUserLocation(UserLocation userLocation) { getUserLocations().add(userLocation); userLocation.setState(this); return userLocation; } public UserLocation removeUserLocation(UserLocation userLocation) { getUserLocations().remove(userLocation); userLocation.setState(null); return userLocation; }}
从UserLocation.java转换的JSON如下:
{ id: 1, addr1: "11905 Technology", addr2: "Eden Prairie", landmark: null, lat: null, lng: null, zipcode: "55344", city: { @id: 1, id: 2, name: "Westborough", state: { @id: 1, id: 2, name: "MA" } }, state: 1}
如您所见,该State
对象作为一个整体进入了内部city
。但是外部的state
(“ UserLocation is showing justan id of
State object. I need to have a same
state object as that of
city
”的属性,而不只是ID。
我对JackSon API比较陌生。请建议我应该采取哪种方法来实现此要求。
谢谢
答案1
小编典典这就是杰克逊设计JsonIdentityInfo批注逻辑的方式。
* Annotation used for indicating that values of annotated type * or property should be serializing so that instances either * contain additional object identifier (in addition actual object * properties), or as a reference that consists of an object id * that refers to a full serialization. In practice this is done * by serializing the first instance as full object and object * identity, and other references to the object as reference values.
Jackson将第一次运行完整的序列化,只有第二次找到该对象时,才会对ID进行序列化。
因此,有两种解决方法:
1)您可以简单地删除@JsonIdentityInfo批注,Jackson将按您期望的方式序列化对象,但将从响应中删除@id字段。这可能很好,因为您仍然会拥有’id’属性。
2)我觉得您可以简单地重组对象并删除一些引用。我会说还是做这些更改是一件好事。首先,您可以从UserLocation中删除对State的引用。我要说的是,因为State附加在City上,所以没有必要将State放在userLocation类中。这样,您将可以从城市访问州,从而解决了您的问题。另外,我将从City类和State类中删除对userLocations列表的引用。
它看起来像:
UserLocation有城市,没有州。
城市有州,没有用户位置
州没有用户位置,也没有城市。
希望这可以帮助
Jackson-将内部对象列表反序列化为更高级别的列表
使用Spring Boot和Jackson,如何将包装/内部列表反序列化为直接在外部级别的列表?
例如,我有:
{ "transaction": { "items": { "item": [ { "itemNumber": "193487654", "itemDescription": "Widget", "itemPrice": "599.00", "itemQuantity": "1", "itemBrandName": "ACME", "itemCategory": "Electronics", "itemTax": "12.95" }, { "itemNumber": "193487654", "itemDescription": "Widget", "itemPrice": "599.00", "itemQuantity": "1", "itemBrandName": "ACME", "itemCategory": "Electronics", "itemTax": "12.95" } ] }, ... }}
在JSON中,item
是items
;
下的列表。但我想将其解析为items
直接位于下方的名为列表的列表transaction
,而不是定义Items
包含名为的列表的DTOitem
。
这可能吗?如何定义此DTO Item
?
public class TrasactionDTO { private List<Item> items; ...}public class Item {}
答案1
小编典典看来这@JsonUnwrapped
就是我所需要的。
https://www.baeldung.com/jackson-
annotations
@JsonUnwrapped 定义在序列化/反序列化时应该解包/展平的值。
让我们确切地了解它是如何工作的。我们将使用注释解开属性名称:
public class UnwrappedUser { public int id; @JsonUnwrapped public Name name; public static class Name { public String firstName; public String lastName; } }
现在让我们序列化此类的实例:
@Testpublic void whenSerializingUsingJsonUnwrapped_thenCorrect() throws JsonProcessingException, ParseException { UnwrappedUser.Name name = new UnwrappedUser.Name("John", "Doe"); UnwrappedUser user = new UnwrappedUser(1, name); String result = new ObjectMapper().writeValueAsString(user); assertThat(result, containsString("John")); assertThat(result, not(containsString("name")));}
输出是这样的-静态嵌套类的字段与其他字段一起展开:
{ "id":1, "firstName":"John", "lastName":"Doe"}
因此,它应该类似于:
public class TrasactionDTO { private List<Item> items; ...}public static class Item { @JsonUnwrapped private InnerItem innerItem; ...}public static class InnerItem { private String itemNumber; ...}
Jackson-将对象内部列表反序列化为更高级别的列表
使用Spring Boot和Jackson,如何将包装/内部列表反序列化为直接在外部级别的列表?
例如,我有:
{
"transaction": {
"items": {
"item": [
{
"itemNumber": "193487654","itemDescription": "Widget","itemPrice": "599.00","itemQuantity": "1","itemBrandName": "ACME","itemCategory": "Electronics","itemTax": "12.95"
},{
"itemNumber": "193487654","itemTax": "12.95"
}
]
},...
}
}
在JSON中,item
是items
;
下的列表。但我想将其解析为items
直接位于下方的名为列表的列表transaction
,而不是定义Items
包含名为的列表的DTO
item
。
这可能吗?如何定义此DTO Item
?
public class TrasactionDTO {
private List<Item> items;
...
}
public class Item {
}
jackson2.1.4 序列化对象时,为NULL的属性不序列化
将该标记放在属性上,如果该属性为NULL则不参与序列化
如果放在类上边,那对这个类的全部属性起作用
Include.Include.ALWAYS 默认
Include.NON_DEFAULT 属性为默认值不序列化
Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化
Include.NON_NULL 属性为NULL 不序列化
@JsonInclude(Include.NON_NULL)
public Date getBirthday() {
return birthday;
}
我们今天的关于Jackson用spring接口列表反序列化对象和springboot jackson反序列化的分享已经告一段落,感谢您的关注,如果您想了解更多关于Jackson 与Spring MVC复制嵌套对象不反序列化、Jackson-将内部对象列表反序列化为更高级别的列表、Jackson-将对象内部列表反序列化为更高级别的列表、jackson2.1.4 序列化对象时,为NULL的属性不序列化的相关信息,请在本站查询。
本文标签: