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
模块
一种类似于与应用程序相关联的子应用程序的概念。
<?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毫秒,并在此期间获取快照。它会为我们转储变量值和内存等信息。