GVKun编程网logo

Jackson用spring接口列表反序列化对象(springboot jackson反序列化)

7

在本文中,您将会了解到关于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接口列表反序列化对象(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复制嵌套对象不反序列化

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 ofState object. I need to have a samestate object as that ofcity
”的属性,而不只是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-将内部对象列表反序列化为更高级别的列表

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中,itemitems;
下的列表。但我想将其解析为items直接位于下方的名为列表的列表transaction,而不是定义Items包含名为的列表的DTO
item

这可能吗?如何定义此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-将对象内部列表反序列化为更高级别的列表

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中,itemitems;
下的列表。但我想将其解析为items直接位于下方的名为列表的列表transaction,而不是定义Items包含名为的列表的DTO
item

这可能吗?如何定义此DTO Item

public class TrasactionDTO {
    private List<Item> items;
    ...
}

public class Item {

}

jackson2.1.4 序列化对象时,为NULL的属性不序列化

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的属性不序列化的相关信息,请在本站查询。

本文标签: