使用 Spring Boot 和 fasterxml jackson 和 @OneToMany 注释将集合添加到 JSON 响应
Adding collection to JSON response using Spring Boot and fasterxml jackson and @OneToMany annotation
我正在使用带有 fasterxml jackson 注释的 spring boot v1.2.3,我试图将整个兄弟集合公开到单个 JSON 响应中,但似乎不能使用正确的注释和神秘代码将添加的集合获取到响应中。
谁能帮我解决这个问题?
我不确定是 spring 引导中的某些东西是原因还是注释之间的配置不正确。我想将子数据库中的集合添加到 json。
@Entity
@Table(name = "station")
public class Station implements Serializable {
@OneToMany(mappedBy = "station", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<StationTank> stationTanks;
@JsonManagedReference("station-tank")
public Set<StationTank> getStationTanks() {
System.out.println("get tank count: " + stationTanks.size());
return stationTanks;
}
public void setStationTanks(Set<StationTank> stationTanks) {
System.out.println("set tank count: " + stationTanks.size());
this.stationTanks = stationTanks;
}
}
@Entity
@Table(name = "station_tank")
public class StationTank implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "station_tank_id")
private long stationTankId;
@Column(name = "active",nullable=true, columnDefinition="Boolean default false")
private Boolean active;
@ManyToOne(cascade = CascadeType.ALL, optional = false) // as defined in schema
@JoinColumn(name = "station_id")
private Station station;
@JsonBackReference("station-tank")
public Station getStation() {
return station;
}
public void setStation(Station station) {
this.station = station;
}
}
调用此 URL 我没有将同级集合添加到响应中,但我希望在响应中添加同级集合。
http://localhost:8080/stations/1
{
"stationId": 1,
"stationName": "station name 1",
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/stations/1"
},
"stationTanks":
{
"href": "http://localhost:8080/stations/1/stationTanks"
}
}
}
但是当我为同级集合调用 URL 时,我得到了同级集合,只是我想要上面响应中的同级集合。
{
"_embedded":
{
"station_tanks":
[
{
"stationTankId": 1,
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/station_tanks/1"
},
"station":
{
"href": "http://localhost:8080/station_tanks/1/station"
}
}
},
{
"stationTankId": 2,
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/station_tanks/2"
},
"station":
{
"href": "http://localhost:8080/station_tanks/2/station"
}
}
}
]
}
}
您可以使用 @JsonView(class)
注释您的字段或 getter,然后在您的控制器方法上使用具有相同 class 的相同注释 - 这是更好的解决方案,或者只是使用 [=11 注释不需要的字段=]
Here 是关于 jackson 配置的更多信息
kxyz 的回答给了我解决方案,但我想为其他人提供更明确的最终解决方案细节。
我没有使用@JsonManagedReference 和@JsonBackReference 注释。
我必须创建以下视图:
public class StationView {
public interface Summary{}
public interface SummaryWithSiblings extends Summary{}
}
和控制器(而不是使用必须在启动时生成的 spring 启动神秘控制器),所以它可以用这个新的 StationView 注释
@RestController
public class StationController {
@Autowired
private StationService stationService;
@JsonView(StationView.SummaryWithSiblings.class)
@RequestMapping("/stations")
public List<Station> getStations() {
Integer clientId = 1234;
return stationService.findByClientId(clientId);
}
}
我注释了每个 class 变量将由 JSON 在父 class 和兄弟 class 上公开。
@JsonView(StationView.Summary.class)
@Column(name = "station_name")
private String stationName;)
和兄弟合集同理
@JsonView(StationView.SummaryWithSiblings.class)
@OneToMany(mappedBy = "station", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<StationTank> stationTanks;
我从 JSON 回复中得到了类似的信息。
[
{
"stationId": 1,
"stationName": "station name 1",
"active": true,
"stationTanks":
[
{
"stationTankId": 1,
"active": true
},
{
"stationTankId": 2,
"active": true
}
]
}
]
我正在使用带有 fasterxml jackson 注释的 spring boot v1.2.3,我试图将整个兄弟集合公开到单个 JSON 响应中,但似乎不能使用正确的注释和神秘代码将添加的集合获取到响应中。
谁能帮我解决这个问题?
我不确定是 spring 引导中的某些东西是原因还是注释之间的配置不正确。我想将子数据库中的集合添加到 json。
@Entity
@Table(name = "station")
public class Station implements Serializable {
@OneToMany(mappedBy = "station", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<StationTank> stationTanks;
@JsonManagedReference("station-tank")
public Set<StationTank> getStationTanks() {
System.out.println("get tank count: " + stationTanks.size());
return stationTanks;
}
public void setStationTanks(Set<StationTank> stationTanks) {
System.out.println("set tank count: " + stationTanks.size());
this.stationTanks = stationTanks;
}
}
@Entity
@Table(name = "station_tank")
public class StationTank implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "station_tank_id")
private long stationTankId;
@Column(name = "active",nullable=true, columnDefinition="Boolean default false")
private Boolean active;
@ManyToOne(cascade = CascadeType.ALL, optional = false) // as defined in schema
@JoinColumn(name = "station_id")
private Station station;
@JsonBackReference("station-tank")
public Station getStation() {
return station;
}
public void setStation(Station station) {
this.station = station;
}
}
调用此 URL 我没有将同级集合添加到响应中,但我希望在响应中添加同级集合。 http://localhost:8080/stations/1
{
"stationId": 1,
"stationName": "station name 1",
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/stations/1"
},
"stationTanks":
{
"href": "http://localhost:8080/stations/1/stationTanks"
}
}
}
但是当我为同级集合调用 URL 时,我得到了同级集合,只是我想要上面响应中的同级集合。
{
"_embedded":
{
"station_tanks":
[
{
"stationTankId": 1,
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/station_tanks/1"
},
"station":
{
"href": "http://localhost:8080/station_tanks/1/station"
}
}
},
{
"stationTankId": 2,
"active": true,
"_links":
{
"self":
{
"href": "http://localhost:8080/station_tanks/2"
},
"station":
{
"href": "http://localhost:8080/station_tanks/2/station"
}
}
}
]
}
}
您可以使用 @JsonView(class)
注释您的字段或 getter,然后在您的控制器方法上使用具有相同 class 的相同注释 - 这是更好的解决方案,或者只是使用 [=11 注释不需要的字段=]
Here 是关于 jackson 配置的更多信息
kxyz 的回答给了我解决方案,但我想为其他人提供更明确的最终解决方案细节。
我没有使用@JsonManagedReference 和@JsonBackReference 注释。
我必须创建以下视图:
public class StationView {
public interface Summary{}
public interface SummaryWithSiblings extends Summary{}
}
和控制器(而不是使用必须在启动时生成的 spring 启动神秘控制器),所以它可以用这个新的 StationView 注释
@RestController
public class StationController {
@Autowired
private StationService stationService;
@JsonView(StationView.SummaryWithSiblings.class)
@RequestMapping("/stations")
public List<Station> getStations() {
Integer clientId = 1234;
return stationService.findByClientId(clientId);
}
}
我注释了每个 class 变量将由 JSON 在父 class 和兄弟 class 上公开。
@JsonView(StationView.Summary.class)
@Column(name = "station_name")
private String stationName;)
和兄弟合集同理
@JsonView(StationView.SummaryWithSiblings.class)
@OneToMany(mappedBy = "station", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<StationTank> stationTanks;
我从 JSON 回复中得到了类似的信息。
[
{
"stationId": 1,
"stationName": "station name 1",
"active": true,
"stationTanks":
[
{
"stationTankId": 1,
"active": true
},
{
"stationTankId": 2,
"active": true
}
]
}
]