简体   繁体   中英

JAX-RS, with JAXB @XmlTransient

I am developing a RESTful service using JAX-RS and JAXB. I have a Complain class, following is a striped down version of it:

@Entity
@Table(name = "complain")
@XmlRootElement
public class Complain implements Serializable {

  private String title;
  private String description;

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "complainidComplain")
   private Collection<Comment> commentCollection;

   @XmlTransient
   public Collection<Comment> getCommentCollection() {
     return commentCollection;
   }
}

Note: I have decorated getCommentCollection with @XmlTransient annotation, because I don't want to see comment when I'm looking for all the complains at @Path("/") .

example.com/api/complain/

<complains>
 <complain>
  <title>Foo</title>
  <description>Foo is foo</description>
 </complain>
 <complain>
  <title>Bar </title>
  <description>Bar is bar</description>
 </complain>
</complains>

But when I'm looking for a specific Complain at @Path("/{id}") , I need the comments to appear in the XML output.

example.com/api/complain/1

<complain>
 <title>Foo</title>
 <description>Foo is foo</description>
 <comments>
  <comment> Yes, i agree </comment>
  <comment> Lorem if foo </comment>
 </comments>
</complain>

Since I have decorated getCommentCollection with @XmlTransient annotation I can't get comments when I'm looking for a specific Complain at @Path("/{id}") . How can I achieve this?

Annotating with @XmlTransient is a compile-time decission so you can't change it dynamically on runtime. As discussed at How to conditionally serialize with JAXB or Jackson you could use Jacksons JsonView or MOXy's external mapping-files .

If you don't want to change your Serializer you could map Complain to a limited Class like eg ComplainPreview which has only the properties title and description . You could also simply set commentCollection to null before returning it in your JAX-RS resource method.

Last (and maybe cleanest) solution: Fetch only the data you want to return from the Database. Therefore you need different queries for your two use cases. You could for instance use a Constructor Expression for the first one:

select new com.yourcompany.Complain(c.title, c.description) from Complain c

Don't forget to add the correspondent Constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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