Scala 如何构建(通用)端点控制器类(层次结构)
我想创建两个端点控制器类(使用Objectify),因为它们共享很多公共代码,所以使用一些通用基类。 我想做这样的事情:Scala 如何构建(通用)端点控制器类(层次结构),scala,google-app-engine,generics,google-cloud-endpoints,objectify,Scala,Google App Engine,Generics,Google Cloud Endpoints,Objectify,我想创建两个端点控制器类(使用Objectify),因为它们共享很多公共代码,所以使用一些通用基类。 我想做这样的事情: @Api( backendRoot = "http://localhost:8888/_ah/spi", root = "http://localhost:8888/_ah/api", version = "v1" ) abstract class BaseController[T <: Entity[T]] { protected def getAp
@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名称(这是基本思想)
唉,端点试图将getApiClass()公开给API,我得到了
java.lang.IllegalArgumentException: Parameterized type java.lang.Class<Misc> not supported
java.lang.IllegalArgumentException:不支持参数化类型java.lang.Class
(好的,我不能在这里省略类型参数化。)
尽管方法受到保护,并且文档声明仅公开公共方法,但仍会发生这种情况。这很可能是因为Scala风格的“受保护”(我只是不知道)。如果它是私有的(如果我不使用类层次结构,它基本上可以工作),我就不能重写它
关于如何使基本想法发挥作用,你有什么线索吗?好问题!下面是我解决这个问题的方法 我的每个端点如下所示:
@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 = {
…
}
…
}
警告:这不是生产就绪代码!(特别要注意的是,我没有使用游标。我不能使用游标,因为我遇到了另一个问题)。
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);
}
}
公共类MyService扩展了抽象服务{
静止的{
ObjectifyService.register(Bean.class);
}
公共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);
}
}
}
公共类抽象服务{
受保护的静态最终记录器Logger=Logger.getLogger(AbstractService.class.getName());
私人期末班idClazz;
当然是私人期末班了!我怎么能如此盲目地忘记了构造函数..谢谢!