简体   繁体   English

在JAX-RS中序列化java.util.list

[英]Serialize a java.util.list in JAX-RS

I have the class book: 我有课本:

@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
        ......................
}

Then, I have class Reservation 然后,我有班级预约

@Entity
@Table(name = "reservations")
@XmlRootElement

public class Reservation {

    private String username;
    private String isbn;
    @Temporal(TemporalType.DATE)
    private Date date;

    @ManyToOne
    @JoinColumn(name = "isbn")
    private Book reservedBook;

    @ManyToOne
    @JoinColumn(name = "username")
    private User userWhoReserved;

        //Getters and setters

        ...........
 }

In the resource class I try to get a specific book like this: 在资源类中,我尝试获取这样的特定书:

@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;

    }

}

Now, it doesn't serialize field List bookReservations. 现在,它没有序列化字段List bookReservations。 I've tried a lot of ideas found on the internet, like annotating the getter for the list with @XmlElement or using other annotations in other places (I don't remember them now), but nothing worked. 我已经尝试了很多在互联网上发现的想法,比如用@XmlElement注释列表的getter或者在其他地方使用其他注释(我现在不记得了),但没有任何效果。

EDIT: This is how a response looks like: 编辑:这是响应的样子:

<book isbn="3333333333">
    <title>Mere Christianity</title>
    <authors>C. S. Lewis</authors>
    <year>2000</year>
</book>

but I also want to show the reservations. 但我也想表明保留意见。

What seems to be the solution? 什么似乎是解决方案? Thanks! 谢谢! Sorin 索林

I think the problem may be with the list bookReservations being null . 我认为问题可能是列表bookReservationsnull

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;
    }
}

I use this code everyday and works for me (Ignore other annotations that I have not provided). 我每天都使用这个代码并为我工作(忽略我没有提供的其他注释)。

I have faced problem in these cases but only found that due to the list being null for some reason it is not serialized. 我在这些情况下遇到了问题,但只发现由于某些原因列表为空而没有序列化。 Try checking whether the list is being set by JAXB in the setter method by debugging at that method. 尝试通过调试该方法检查JAXB是否在setter方法中设置列表。

My wild guest is that it's the problem of lazy loading, you may adding fetch = FetchType.EAGER in OneToMany and ManyToOne annotations. 我的狂野客人是延迟加载的问题,你可以在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
        ......................
    }

And in Reservation class: 在预订课程中:

 public class Reservation {

    private String username;
    private String isbn;
    @Temporal(TemporalType.DATE)
    private Date date;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "isbn")
    private Book reservedBook;

    @ManyToOne
    @JoinColumn(name = "username")
    private User userWhoReserved;

        //Getters and setters

        ...........
 }

Use @XmlAccessorType.PROPERTY instead of FIELD . 使用@XmlAccessorType.PROPERTY而不是FIELD The JPA impl may be lazy loading the list of reservations, this action will be triggered by accessing the property (get method). JPA impl可能是延迟加载预留列表,此操作将通过访问属性(get方法)触发。

For More Information 欲获得更多信息

Solved! 解决了! But the problem was not the serializing, but the fact that method find() called by the EntityManager could not extract the reservations and put them into my book object, so the list remained empty and its corresponding element was not displayed. 但问题不在于序列化,而是由EntityManager调用的方法find()无法提取保留并将它们放入我的book对象这一事实,因此列表保持为空并且未显示相应的元素。 So, instead of using find(), it seems that one should use Query: 所以,而不是使用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
    }

Also, the @XmlAccessorType(XmlAccessType.FIELD) must be deleted from the Book class and the getter for the list should be annotated with @XmlElementWrapper(name = "reservations") and @XmlElement(name = "reservation"). 此外,必须从Book类中删除@XmlAccessorType(XmlAccessType.FIELD),并且应使用@XmlElementWrapper(name =“reservations”)和@XmlElement(name =“reservation”)注释列表的getter。

Wrap with an @XmlRootelement with nillable="true" then an empty <reservations> will be there. 使用带有nillable="true"@XmlRootelement换行,然后将出现一个空的<reservations>

@XmlElement
@XmlElementWrapper(nillable=true)
private List<Reservation> bookReservations;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM