我在 Glassfish 3.1.2 服务器上运行 RESTful Web 服务。我使用 Jersey 作为 JAX-RS 实现,Jackson 作为它的 JSON 提供者,以及 (JPA) EclipseLink 2.5 作为 MySQL 的持久性提供者。
我将介绍一些上下文,然后问我的问题。假设我们有以下层次结构:Item
实体和CraftableItem
继承它的实体(参见下面的代码示例)。它们都有对应的 EAO 和 Resource 类:ItemEAO
, CraftableItemEAO
+ ItemResource
, CraftableItemResource
(参见下面的代码示例)。
让我们在表中有两条记录items
:
id | name
1 | "craftable"
2 | "non craftable"
以及“可制作”的相应记录crafting_items_joined
:
id | crafting_time
1 | 120000
我想从GET /item
请求中尽可能多地获取有关每个实体的具体信息。我希望它返回[{"id":1,"name":"craftable", "crafting_time":120000}, {"id":2,"name":"non craftable"}]
。此刻,GET /item/1
返回{"id":1,"name":"craftable", "crafting_time":120000}
并GET /item/2
返回正是{"id":2,"name":"non craftable"}
我想要的行为,但对于GET /item
. 获取有关实体存在的所有信息。
代码示例(为了理智起见,省略了设置器)。
@MappedSuperclass
public abstract class BaseEntity {
protected Long id;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "items")
public class Item extends BaseEntity implements Serializable {
private String name;
@Column(name = "name", nullable = false, unique = true)
public String getName() {
return name;
}
}
@Entity
@DiscriminatorValue("craftable")
@Table(name = "craftable_items_joined")
public class CraftableItem extends Item {
protected long craftingTime;
@Column(name = "crafting_time", nullable = false)
public long getCraftingTime() {
return craftingTime;
}
}
然后EAO:
public abstract class AbstractEAO<T> {
private Class<T> entityClass;
public AbstractEAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
public Class<T> getEntityClass() {
return entityClass;
}
protected abstract EntityManager getEntityManager();
// create, edit, remove
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
}
@Stateless
@LocalBean
public class ItemEAO extends AbstractEAO<Item> {
@PersistenceContext(unitName = "primary")
private EntityManager entityManager;
public ItemEAO() {
super(Item.class);
}
@Override
protected EntityManager getEntityManager() {
return entityManager;
}
}
@Stateless
@LocalBean
public class CraftableItemEAO extends AbstractEAO<CraftableItem> {
@PersistenceContext(unitName = "primary")
private EntityManager entityManager;
public CraftableItemEAO() {
super(CraftableItem.class);
}
@Override
protected EntityManager getEntityManager() {
return entityManager;
}
}
最后资源:
public abstract class AbstractResource<T extends BaseEntity> {
protected abstract AbstractEAO<T> getEAO();
@GET
public List<T> findAll() {
return getEAO().findAll();
}
@GET
@Path("{id}")
public T find(@PathParam("id") Long id) {
return getEAO().find(id);
}
// create, edit, remove
}
@Stateless
@Path("item")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ItemResource extends AbstractResource<Item> {
@EJB private ItemEAO itemEAO;
@Override
protected AbstractEAO<Item> getEAO() {
return itemEAO;
}
}
@Stateless
@Path("item/craftable")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CraftableItemResource extends AbstractResource<CraftableItem> {
@EJB private CraftableItemEAO craftableItemEAO;
@Override
protected AbstractEAO<CraftableItem> getEAO() {
return craftableItemEAO;
}
}