我正在尝试将以下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 is showing just an id of
国家object. I need to have a same
州object as that of
城市`的属性,而不仅仅是id。
我对JackSon api相对较新。请告知我应该遵循哪种方法来实现这一要求。
谢谢
答案 0 :(得分:5)
这是杰克逊设计的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.
杰克逊将首次运行完整的序列化,只有当第二次找到该对象时,才会序列化id。
因此,有两种方法可以解决它:
1)您可以简单地删除@JsonIdentityInfo注释,Jackson将按预期序列化对象,但它将从响应中删除@id字段。这可能很好,因为你仍然会有&#39; id&#39;属性。
2)我觉得你可以简单地重构你的对象并删除一些引用。我会说无论如何做这些改变都是好的。首先,您可以从UserLocation删除对State的引用。我会说,由于State附加到City,因此没有必要将State置于userLocation类中。 通过这样做,您将从城市访问状态,您的问题就解决了。 另外,我会从City类和State类中删除对userLocations列表的引用。
看起来像:
UserLocation拥有City且没有State。
城市有州,没有userLocations
State没有userLocations和city。
希望这有帮助
答案 1 :(得分:0)
首先从State.java和City.java中删除该注释
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = State.class)
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = City.class)
不需要这些注释,并且在RestController中添加返回类型为@ResponseBody UserLocation。它将为你提供该类的json。