我正在使用JAX-RS和JAXB开发RESTful服务。我有一个Complain类,以下是其简化版本:

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


注意:我已经用getCommentCollection注释修饰了@XmlTransient,因为在查找@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>


但是,当我在Complain上寻找特定的@Path("/{id}")时,我需要注释出现在XML输出中。

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>


由于用getCommentCollection注释装饰了@XmlTransient,因此当我在Complain上查找特定的@Path("/{id}")时无法获得注释。我该如何实现?

最佳答案

@XmlTransient注释是编译时的决定,因此您不能在运行时动态更改它。如How to conditionally serialize with JAXB or Jackson所述,您可以使用Jacksons JsonViewMOXy's external mapping-files

如果您不想更改序列化器,则可以将Complain映射到有限的类,例如ComplainPreview仅具有属性titledescription。您还可以将commentCollection设置为null,然后再使用JAX-RS资源方法将其返回。

最后一种(也许是最干净的)解决方案:仅获取要从数据库返回的数据。因此,对于两个用例,您需要不同的查询。例如,您可以为第一个使用Constructor Expression

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


不要忘了添加对应的构造函数。

10-06 08:58