我在Glassfish 3.1.2服务器上运行RESTful Web服务。我使用Jersey作为JAX-RS实现,Jackson作为json提供程序使用(JPA)EclipseLink 2.5作为MySQL的持久性提供程序。
我将介绍一些背景,然后问我的问题。
假设我们有以下层次结构:Item
实体和继承它的CraftableItem
实体(请参阅下面的代码示例)。它们都有相应的EAO和资源类:ItemEAO
,CraftableItemEAO
+ ItemResource
,CraftableItemResource
(请参阅下面的代码示例)。
我们在items
表中有两条记录:
id | name
1 | "craftable"
2 | "non craftable"
和crafting_items_joined
中“craftable”的一条相应记录:
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
。获取有关实体的所有信息。
代码示例(出于理智而省略了setter)。
@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;
}
}