Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何构建(通用)端点控制器类(层次结构)_Scala_Google App Engine_Generics_Google Cloud Endpoints_Objectify - Fatal编程技术网

Scala 如何构建(通用)端点控制器类(层次结构)

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

我想创建两个端点控制器类(使用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名称(这是基本思想)

唉,端点试图将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;

当然是私人期末班了!我怎么能如此盲目地忘记了构造函数..谢谢!