java - 具有 Spring MVC 的 Jackson 重复嵌套对象不反序列化

标签 java json rest spring-mvc jackson

我正在尝试将以下 POJO 转换为 @RestController 中的 JSON:

@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 的属性只显示 State 对象的 id。我需要有一个相同的state对象作为city` 而不仅仅是 id。

我对 JackSon api 比较陌生。请建议我应该采用哪种方法来实现此要求。

谢谢

最佳答案

jackson就是这样设计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 的引用。我会说没有必要在 userLocation 类中有状态,因为状态附加到城市。 通过这样做,您将从城市访问州,您的问题就解决了。 此外,我将从 City 类和 State 类中删除对 userLocations 列表的引用。

它看起来像:

UserLocation 有 City,没有 State。

City 有 State 但没有 userLocations

州没有用户位置和城市。

希望对你有帮助

关于java - 具有 Spring MVC 的 Jackson 重复嵌套对象不反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27109953/

相关文章:

json - 使用 jq 提取类似文件夹的 JSON 结构中的完整路径

json - 注册。带有jqgrid的json中的日期格式问题

java - 在 Java 中使用列表和映射来使用大型嵌套数据结构是否可以?

java - 当某些字符串具有不同长度时,如何格式化多个字符串以获得相等的间距

java - 生成属于两个不同范围的 rand 值

rest - Angular 2 创建模型与动态处理 json 对象?

asp.net-mvc - 构建与数据格式分离的 ASP.NET MVC REST API 代码的最佳方法?

java - 如何让 Spring 接受流畅(非 void)的 setter ?

Python:JSON 中无法识别字符串变量,但硬编码字符串可以工作(Instagram API)

javascript - 如何将 promise 的数据打印到网页?