Google App Engine for Java 综述

图书馆的组成

    • RestAPI: Jersey

 

    • Data Binding: MOXy

 

    DataStoreAPI: Objectify

数据存储服务

对象数据库。基于BigTable的一种。

    • カインド(kind)

RDBのtableに相当

エンティティ(entity)

RDBのレコードに相当

プロパティ(property)

RDBのフィールドに相当

在Java中,进行数据的CRUD操作,可以使用谷歌制作的名为Objectify的库,使用它会更加方便。

实体的定义 de

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;

@Entity
public class Car {
    @Id Long id;
    @Index String license;
    int color;
}

保存

    public Car create() {
        Car car = new Car("toyoya", 1234);
        ofy().save().entity(car).now();
    }

获取

Result<Car> result = ofy().load().key(Key.create(Car.class, id));

列表

Result<Car> result = ofy().load().key(Key.create(Car.class, id));

查询

// Operators are >, >=, <, <=, in, !=, <>, =, ==
List<Car> cars = ofy().load().type(Car.class).filter("year >", 1999).list();
List<Car> cars = ofy().load().type(Car.class).filter("year >=", 1999).list();
List<Car> cars = ofy().load().type(Car.class).filter("year !=", 1999).list();
List<Car> cars = ofy().load().type(Car.class).filter("year in", yearList).list();

// The Query itself is Iterable
Query<Car> q = ofy().load().type(Car.class).filter("vin >", "123456789");
for (Car car: q) {
    System.out.println(car.toString());
}

索引

只要在基本@Index中进行设置,Index就会被配置。
然而,对于自定义索引(在指定多个条件的情况下),需要创建datastore-indexes.xml。

请你给我一个水杯的例子。
请你举个水杯的实例。

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
  autoGenerate="true">
    <datastore-index kind="Employee" ancestor="false">
        <property name="lastName" direction="asc" />
        <property name="hireDate" direction="desc" />
    </datastore-index>
    <datastore-index kind="Project" ancestor="false">
        <property name="dueDate" direction="asc" />
        <property name="cost" direction="desc" />
    </datastore-index>
</datastore-indexes>

交易

虽然有一些限制,但仍有可能使用,不是完全无法使用。

import static com.googlecode.objectify.ObjectifyService.ofy;
import com.googlecode.objectify.Work;

// If you don't need to return a value, you can use VoidWork
Thing th = ofy().transact(new Work<Thing>() {
    public Thing run() {
        Thing thing = ofy().load().key(thingKey).now();
        thing.modify();
        ofy().save().entity(thing);
        return thing;
    }
});

用户服务

简化使得用户可以轻松使用诸如使用Google账户进行用户认证等机制的服务。
例如,只将某个URL设为Google认证,或者仅给予特定用户认证许可等。
还可以在操作员界面上放置,或者在发布前仅允许特定用户通过Google认证查看等。
只需要在WebXML中进行设置即可。

内存缓存服务

Objectify提供了一种方式,可以在需要快速且临时存储数据的情况下,以内存方式存储数据,而不是使用Google Cloud Datastore或Cloud SQL等持久性数据存储机制。它还提供了将数据同时保存到Memcache的机制。

任务队列服务

所谓的队列。存在着两种类型的队列。

    • Push Queue

enqueueしたら即座にdequeue処理される。

Pull Queue

特定のタイミングでdequeueしたい場合に利用できる。

将…加入队列

public class Enqueue extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String key = request.getParameter("key");

        // Add the task to the default queue.
        Queue queue = QueueFactory.getDefaultQueue();
        queue.add(TaskOptions.Builder.withUrl("/worker").param("key", key));

        response.sendRedirect("/");
    }
}

取出队列中的元素

// The Worker servlet should be mapped to the "/worker" URL.
public class Worker extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String key = request.getParameter("key");
        // Do something with key.
    }
}

dequeue的机制是在enqueue时,通过http方式发送处理请求给指定的路径。

定时任务服务(Cron)

所谓的cron。设置cron.xml进行配置。
为每个cron准备相应的终点(Servlet),并在Servlet中编写处理逻辑。

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
  <cron>
    <url>/recache</url>
    <description>Repopulate the cache every 2 minutes</description>
    <schedule>every 2 minutes</schedule>
  </cron>
  <cron>
    <url>/weeklyreport</url>
    <description>Mail out a weekly report</description>
    <schedule>every monday 08:30</schedule>
    <timezone>America/New_York</timezone>
  </cron>
  <cron>
    <url>/weeklyreport</url>
    <description>Mail out a weekly report</description>
    <schedule>every monday 08:30</schedule>
    <timezone>America/New_York</timezone>
    <target>version-2</target>
  </cron>
</cronentries>

渠道服务

可以实现类似名为PubSub的服务。我认为可以实现类似聊天的功能。我会详细调查。

图像服务

这是一个可以轻松调整图片大小、裁剪和旋转的服务。

import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;

// ...
        byte[] oldImageData;  // ...

        ImagesService imagesService = ImagesServiceFactory.getImagesService();

        Image oldImage = ImagesServiceFactory.makeImage(oldImageData);
        Transform resize = ImagesServiceFactory.makeResize(200, 300);

        Image newImage = imagesService.applyTransform(resize, oldImage);

        byte[] newImageData = newImage.getImageData();

Blobstore中保存的图片等可以通过向URL添加查询来访问,系统会自动进行缩放和裁剪。

# Resize the image to 32 pixels (aspect-ratio preserved)
http://lhx.ggpht.com/randomStringImageId=s32

# Crop the image to 32 pixels
http://lhx.ggpht.com/randomStringImageId=s32-c

模块

一种类似于与应用程序相关联的子应用程序的概念。

modules_hierarchy.png
<?xml version="1.0" encoding="UTF-8"?>
<dispatch-entries>
  <dispatch>
      <!-- Default module serves the typical web resources and all static resources. -->
      <url>*/favicon.ico</url>
      <module>default</module>
  </dispatch>
  <dispatch>
      <!-- Default module serves simple hostname request. -->
      <url>simple-sample.appspot.com/</url>
      <module>default</module>
  </dispatch>
  <dispatch>
      <!-- Send all mobile traffic to the mobile frontend. -->
      <url>*/mobile/*</url>
      <module>mobile-frontend</module>
  </dispatch>
  <dispatch>
      <!-- Send all work to the one static backend. -->
      <url>*/work/*</url>
      <module>static-backend</module>
  </dispatch>
</dispatch-entries>

可以用于类似于微服务的机制。同时,通过编写dispatch.xml文件,可以将请求委托给指定的模块处理,根据URL路径的不同。

云调试

太厉害了。在正式环境中运行的服务源代码上放置调试器,可以进行调试。目前仅支持Java。
安装调试器后,大约会停止20毫秒,并在此期间获取快照。它会为我们转储变量值和内存等信息。

广告
将在 10 秒后关闭
bannerAds