在JAX-RS中序列化java.util.list
我有一本教科书:在JAX-RS中序列化java.util.list,java,web-services,jpa,jaxb,jax-rs,Java,Web Services,Jpa,Jaxb,Jax Rs,我有一本教科书: @Entity @Table(name = "books") @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType public class Book { @Id @XmlAttribute private String isbn; private String title; private String authors; private int year
@Entity
@Table(name = "books")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public class Book {
@Id
@XmlAttribute
private String isbn;
private String title;
private String authors;
private int year;
@OneToMany(mappedBy="reservedBook")
private List<Reservation> bookReservations;
//Getters, setters, addReservation, remove Reservation
......................
}
在资源类中,我尝试获得一本具体的书,如下所示:
@GET
@Path("/{isbn}")
@Produces(MediaType.TEXT_XML)
public Book getBookByIsbn(@PathParam("isbn") String isbn) {
Book book = entityManager.find(Book.class, isbn);
if (book != null) {
return book;
}
}
现在,它不会序列化字段列表bookReservations。我尝试了很多在互联网上找到的想法,比如用@xmlement为列表注释getter,或者在其他地方使用其他注释(我现在不记得了),但是没有任何效果
编辑:这是响应的外观:
<book isbn="3333333333">
<title>Mere Christianity</title>
<authors>C. S. Lewis</authors>
<year>2000</year>
</book>
返璞归真
刘易斯
2000
但我也想展示一下预订情况
解决办法似乎是什么?
谢谢
Sorin我认为问题可能在于列表
bookReservations
为null
class A{
private List<String> someList = new ArrayList<String>();
@XmlElement(name = "some-tag")
public List<String> getList() {
return someList;
}
public void setSomeList(List<String> someOtherList) {
this.someList = someOtherList;
}
}
A类{
private List someList=new ArrayList();
@xmlement(name=“some标记”)
公共列表getList(){
返回一些列表;
}
public void setSomeList(List someOtherList){
this.someList=someOtherList;
}
}
我每天都使用这段代码,并为我工作(忽略我没有提供的其他注释)
我在这些情况下遇到了问题,但只发现由于某种原因列表为空,所以它没有序列化。通过调试setter方法,尝试检查列表是否由JAXB在setter方法中设置。使用
@xmlacessortype.PROPERTY
而不是字段。JPA impl可能延迟加载保留列表,此操作将通过访问属性(get方法)触发
了解更多信息
我的不速之客是,这是延迟加载的问题,您可以在OneToMany和ManyToOne注释中添加fetch=FetchType.EAGER
public class Book {
@Id
@XmlAttribute
private String isbn;
private String title;
private String authors;
private int year;
@OneToMany(mappedBy="reservedBook",fetch = FetchType.EAGER)
private List<Reservation> bookReservations;
//Getters, setters, addReservation, remove Reservation
......................
}
解决了!但问题不在于序列化,而是EntityManager调用的find()方法无法提取保留并将其放入my book对象,因此列表仍然为空,其相应的元素没有显示。因此,与其使用find(),不如使用Query:
Query query = entityManager.createQuery("SELECT book FROM Book book WHERE book.isbn = :_isbn ");
query.setParameter("_isbn", isbn);
//if getSingleResult() doesn't find a book, an exception will be thrown
try {
Book book = (Book)query.getSingleResult();
return book;
}
catch(RuntimeException e)
{
//do something
}
此外,必须从Book类中删除@XmlAccessorType(XmlAccessType.FIELD),列表的getter应该用@XmlElementWrapper(name=“reservations”)和@XmlElement(name=“reservations”)进行注释。用@XmlRootelement
用nillable=“true”
进行包装,然后将出现一个空的
@XmlElement
@XmlElementWrapper(nillable=true)
private List<Reservation> bookReservations;
@xmlement
@XmlElementWrapper(nillable=true)
私人列表预订;
您是否尝试在OneToMany和ManyToOne批注中添加fetch=FetchType.EAGER?@Thinbk:我已经解决了问题…我发布了解决方案。是的,它为空,但由于EntityManager.find()方法无法获取它…但您通常使用EntityManager.find()或查询来获取结果吗?find()方法似乎没有提取保留并将它们放入my Book对象中……您必须配置@OneToMany(fetch=FetchType.EAGER,mappedBy=“reservedBook”)私有列表bookReservations代码>我已经按照我发布为答案的方式完成了,现在它可以工作了…但是,如果我按照你说的那样做,它是否可以与entityManager.find()一起工作?是的,它应该可以工作,如果你不将它配置为“急切”,那么它就不会获取关系记录。
Query query = entityManager.createQuery("SELECT book FROM Book book WHERE book.isbn = :_isbn ");
query.setParameter("_isbn", isbn);
//if getSingleResult() doesn't find a book, an exception will be thrown
try {
Book book = (Book)query.getSingleResult();
return book;
}
catch(RuntimeException e)
{
//do something
}
@XmlElement
@XmlElementWrapper(nillable=true)
private List<Reservation> bookReservations;