我想创建几个端点控制器类(使用Objectify),并且因为它们共享许多公共代码,所以使用一些通用基类。 我想做这样的事情:
@Api(
backendRoot = "http://localhost:8888/_ah/spi",
root = "http://localhost:8888/_ah/api",
version = "v1"
)
abstract class BaseController[T <: Entity[T]] {
protected def getApiClass() : Class[T]
@ApiMethod(
name = "read",
path = "read",
httpMethod = HttpMethod.GET
)
def read() : JList[T] = {
OfyS.ofy().load().`type`(getApiClass()).list().asInstanceOf[JList[T]]
}
def create(entity : T) : T = {
…
}
…
}
和
@Api(
name = "misc"
)
class MiscController extends BaseController[Misc] {
override protected def getApiClass() = classOf[Misc]
}
作为几个实现之一。这样,我基本上只需要在每个实现中替换类型和API名称(这是基本的想法)。
唉,Endpoints尝试将getApiClass()公开给API,我得到了
java.lang.IllegalArgumentException: Parameterized type java.lang.Class<Misc> not supported
(afaik,我不能在这里省略类型参数化。)
虽然该方法受到保护且文档声明只公开公共方法,但仍会发生这种情况。这可能是因为Scala的'protected'味道(我根本就不知道)。如果它是私有的(如果我没有使用类层次结构,它基本上有效),我无法覆盖它。
您是否有任何关于如何使基本想法发挥作用的线索?
答案 0 :(得分:0)
好问题!以下是我如何解决这个问题...
我的端点中的每一个都是这样的:
警告:这不是生产就绪代码! (特别是,请注意我没有使用光标。由于我面临的问题不同,我无法做到。)
public class MyEndpoint {
@ApiMethod(
name = "get",
path = "bean/{id}",
httpMethod = ApiMethod.HttpMethod.GET)
public Bean get(@Named("id") Long id) throws NotFoundException {
return new MyService().get(id);
}
...
}
现在,让我们看一下 MyService 类:
public class MyService extends AbstractService<Long, Bean> {
static {
ObjectifyService.register(Bean.class);
}
public MyService() {
super(Long.class, Bean.class);
}
}
最后, AbstractService :
public class AbstractService<D, T> {
protected static final Logger logger = Logger.getLogger(AbstractService.class.getName());
private final Class<?> idClazz;
private final Class<? extends T> clazz;
public AbstractService(Class<?> idClazz, Class<? extends T> clazz) {
this.idClazz = idClazz;
this.clazz = clazz;
}
public T get(D id) throws NotFoundException {
logger.info("Getting " + clazz.getName() + " with ID: " + id);
T obj = null;
if (idClazz == Long.class) {
Long parsedId = (Long) id;
obj = ofy().load().type(clazz).id(parsedId).now();
} else if (idClazz == String.class) {
String parsedId = (String) id;
obj = ofy().load().type(clazz).id(parsedId).now();
}
if (obj == null) {
throw new NotFoundException("Could not find " + getClass().getName() + " with ID: " + id);
}
return obj;
}
public T insert(T obj) {
ofy().save().entity(obj).now();
logger.info("Created " + clazz.getName() + ".");
return ofy().load().entity(obj).now();
}
public T update(D id, T obj) throws NotFoundException {
checkExists(id);
ofy().save().entity(obj).now();
logger.info("Updated " + clazz.getName() + ": " + obj);
return ofy().load().entity(obj).now();
}
public void remove(D id) throws NotFoundException {
checkExists(id);
T obj = null;
if (idClazz == Long.class) {
Long parsedId = (Long) id;
ofy().delete().type(clazz).id(parsedId).now();
} else if (idClazz == String.class) {
String parsedId = (String) id;
ofy().delete().type(clazz).id(parsedId).now();
}
logger.info("Deleted " + getClass().getName() + " with ID: " + id);
}
public CollectionResponse<T> list() {
// limit = limit == null ? DEFAULT_LIST_LIMIT : limit;
logger.info("Listing " + clazz.getName() + "s");
Query<? extends T> query = ofy().load().type(clazz);
QueryResultIterator<? extends T> queryIterator = query.iterator();
List<T> objList = new ArrayList<T>();
while (queryIterator.hasNext()) {
objList.add(queryIterator.next());
}
return CollectionResponse.<T>builder().setItems(objList).build();
}
public CollectionResponse<T> list(int limit, int startAt) {
logger.info("Listing " + clazz.getName() + "s");
Query<? extends T> query = ofy().load().type(clazz).offset(startAt).limit(limit);
QueryResultIterator<? extends T> queryIterator = query.iterator();
List<T> objList = new ArrayList<T>();
while (queryIterator.hasNext()) {
objList.add(queryIterator.next());
}
return CollectionResponse.<T>builder().setItems(objList).build();
}
private void checkExists(D id) throws NotFoundException {
try {
if (idClazz == Long.class) {
Long parsedId = (Long) id;
ofy().load().type(clazz).id(parsedId).safe();
} else if (idClazz == String.class) {
String parsedId = (String) id;
ofy().load().type(clazz).id(parsedId).safe();
}
} catch (com.googlecode.objectify.NotFoundException e) {
throw new NotFoundException("Could not find " + getClass().getName() + " with ID: " + id);
}
}
}