我有一个Java RESTapi,在这里我想将我的自定义Pet对象的列表转换为Json,并在一个端点中显示它。
目前为止,我的代码如下:
@Path("/allPets")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPetsfromCollection() {
List<Pet> petList = new ArrayList<>();
petList.addAll(facade.returnAllPets());
String json = gson.toJson(petList);
//TODO return proper representation object
return Response.ok().entity(json).build();
}
我正在使用门面模式,其中我有一个方法将Java实体添加到列表中,如下所示:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PetHospitaljpa");
public Collection<Pet> returnAllPets (){
EntityManager em = emf.createEntityManager();
//vi laver en typed query for at specificere hvilken datatype,
// det er vi leder efter, i dette tilfælde er det en Pet
TypedQuery<Pet> query = em.createNamedQuery("Pet.findAll", Pet.class);
return query.getResultList();
}
我返回一个集合,以便以后可以将ArrayList的数据结构更改为其他内容。
我尝试了几种解决方法,但仍然出现堆栈溢出错误。
我知道需要使用DTO代替,因此我已经创建了一个自定义方法将实体更改为DTO,如下所示:
public static DTOPet converttoDTO(Pet entity){
DTOPet dto = new DTOPet();
dto.setId(entity.getId());
dto.setName(entity.getName());
dto.setBirth(entity.getBirth());
dto.setDeath(entity.getDeath());
dto.setSpecies(entity.getSpecies());
return dto;
}
我不确定是否这是良好的代码实践,如果有其他方法可以将实体集合转换为DTO,请告诉我?
如前所述。问题发生是因为我有循环引用。
在我的Pet Entity类中:
@ManyToOne
private Owner ownerId;
在我的所有者实体类中:
@OneToMany(mappedBy = "ownerId")
private Collection<Pet> petCollection;
我的宠物课:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Entities;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* @author kristoffer
*/
@Entity
@Table(name = "pet")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Pet.findAll", query = "SELECT p FROM Pet p")
, @NamedQuery(name = "Pet.findById", query = "SELECT p FROM Pet p WHERE p.id = :id")
, @NamedQuery(name = "Pet.findByName", query = "SELECT p FROM Pet p WHERE p.name = :name")
, @NamedQuery(name = "Pet.findByBirth", query = "SELECT p FROM Pet p WHERE p.birth = :birth")
, @NamedQuery(name = "Pet.findBySpecies", query = "SELECT p FROM Pet p WHERE p.species = :species")
, @NamedQuery(name = "Pet.findByDeath", query = "SELECT p FROM Pet p WHERE p.death = :death")})
public class Pet implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "name")
private String name;
@Basic(optional = false)
@NotNull
@Column(name = "birth")
@Temporal(TemporalType.DATE)
private Date birth;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "species")
private String species;
@Column(name = "death")
@Temporal(TemporalType.DATE)
private Date death;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "petId")
private Collection<Event> eventCollection;
@JoinColumn(name = "owner_id", referencedColumnName = "id")
@ManyToOne
private Owner ownerId;
public Pet() {
}
public Pet(Integer id) {
this.id = id;
}
public Pet(Integer id, String name, Date birth, String species) {
this.id = id;
this.name = name;
this.birth = birth;
this.species = species;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public Date getDeath() {
return death;
}
public void setDeath(Date death) {
this.death = death;
}
@XmlTransient
public Collection<Event> getEventCollection() {
return eventCollection;
}
public void setEventCollection(Collection<Event> eventCollection) {
this.eventCollection = eventCollection;
}
public Owner getOwnerId() {
return ownerId;
}
public void setOwnerId(Owner ownerId) {
this.ownerId = ownerId;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Pet)) {
return false;
}
Pet other = (Pet) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "Pet{" + "id=" + id + ", name=" + name + ", birth=" + birth + ", species=" + species + ", death=" + death + ", eventCollection=" + eventCollection + ", ownerId=" + ownerId + '}';
}
}
编辑: 我尝试创建一个方法,将所有对象转换为DTO,但在显示时该字符串仍为空:
@Path("/allPets")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPetsfromCollection() {
//med denne metode skal vi bruge et DTO(data transfer object til at formatere til Json)
List<Pet> petList = new ArrayList<>();
List<DTOPet> DTOPetList = new ArrayList<>();
petList.addAll(facade.returnAllPets());
for(Pet pet: petList){
DTOPet dtopet = EntitytoDTO.converttoDTO(pet);
DTOPetList.add(dtopet);
}
String json = gson2.toJson(DTOPetList);
return Response.ok().entity(json).build();
}
当我使用调试器时,新的列表已成功创建,并且参数正确,但是字符串JSON只是像这样创建的
[{},{},{},{}]
,尽管我使用了GSON。