我正在学习将EndPoints编程到Google-App-Engine,而且我直接与谷歌服务器合作,而不是本地。
在控制台谷歌中,我激活了API:Google Cloud Datastore API,Google Cloud Storage和Android Google Maps API v2。
我使用了我在下面描述的教程中找到的一个例子:
我有这个实体:
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
@Entity
public class Quote {
@Id
Long id;
String who;
String what;
public Quote() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
public String getWhat() {
return what;
}
public void setWhat(String what) {
this.what = what;
}
}
此EndPoint类:
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.config.Nullable;
import com.google.api.server.spi.response.CollectionResponse;
import com.google.api.server.spi.response.ConflictException;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.googlecode.objectify.cmd.Query;
import static com.ringtheapp.parche.OfyService.ofy;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Named;
@Api(name = "quoteEndpoint", version = "v1", namespace = @ApiNamespace(ownerDomain = "parche.mydomine.com", ownerName = "parche.mydomine.com", packagePath=""))
public class QuoteEndpoint {
// Make sure to add this endpoint to your web.xml file if this is a web application.
public QuoteEndpoint() {
}
/**
* Return a collection of quotes
*
* @param count The number of quotes
* @return a list of Quotes
*/
@ApiMethod(name = "listQuote")
public CollectionResponse<Quote> listQuote(@Nullable @Named("cursor") String cursorString,
@Nullable @Named("count") Integer count) {
Query<Quote> query = ofy().load().type(Quote.class);
if (count != null) query.limit(count);
if (cursorString != null && cursorString != "") {
query = query.startAt(Cursor.fromWebSafeString(cursorString));
}
List<Quote> records = new ArrayList<Quote>();
QueryResultIterator<Quote> iterator = query.iterator();
int num = 0;
while (iterator.hasNext()) {
records.add(iterator.next());
if (count != null) {
num++;
if (num == count) break;
}
}
//Find the next cursor
if (cursorString != null && cursorString != "") {
Cursor cursor = iterator.getCursor();
if (cursor != null) {
cursorString = cursor.toWebSafeString();
}
}
return CollectionResponse.<Quote>builder().setItems(records).setNextPageToken(cursorString).build();
}
/**
* This inserts a new <code>Quote</code> object.
* @param quote The object to be added.
* @return The object to be added.
*/
@ApiMethod(name = "insertQuote")
public void insertQuote(Quote quote) throws ConflictException {
//If if is not null, then check if it exists. If yes, throw an Exception
//that it is already present
if (quote.getId() != null) {
if (findRecord(quote.getId()) != null) {
throw new ConflictException("Object already exists");
}
}
//Since our @Id field is a Long, Objectify will generate a unique value for us
//when we use put
ofy().save().entity(quote).now();
}
/**
* This updates an existing <code>Quote</code> object.
* @param quote The object to be added.
* @return The object to be updated.
*/
@ApiMethod(name = "updateQuote")
public Quote updateQuote(Quote quote)throws NotFoundException {
if (findRecord(quote.getId()) == null) {
throw new NotFoundException("Quote Record does not exist");
}
ofy().save().entity(quote).now();
return quote;
}
/**
* This deletes an existing <code>Quote</code> object.
* @param id The id of the object to be deleted.
*/
@ApiMethod(name = "removeQuote")
public void removeQuote(@Named("id") Long id) throws NotFoundException {
Quote record = findRecord(id);
if(record == null) {
throw new NotFoundException("Quote Record does not exist");
}
ofy().delete().entity(record).now();
}
//Private method to retrieve a <code>Quote</code> record
private Quote findRecord(Long id) {
return ofy().load().type(Quote.class).id(id).now();
//or return ofy().load().type(Quote.class).filter("id",id).first.now();
}
}
我有这个Ofy课程:
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
/**
* Objectify service wrapper so we can statically register our persistence classes
* More on Objectify here : https://code.google.com/p/objectify-appengine/
*
*/
public class OfyService {
static {
ObjectifyService.register(Quote.class);
ObjectifyService.register(Post.class);
}
public static Objectify ofy() {
return ObjectifyService.ofy();
}
public static ObjectifyFactory factory() {
return ObjectifyService.factory();
}
}
当我转到API资源管理器时,使用这种地址格式&#34; https://apis-explorer.appspot.com/apis-explorer/?base=https://1-dot-myproyectname.appspot.com/_ah/api#p/&#34; ,它运行正常,它给了我5个实体,但是当我在计数字段中运行方法listQuote时,它将不会返回我的nextPageToken。
它给我这个计数= 2:
200 OK
- Show headers -
{
"items": [
{
"id": "5629499534213120",
"who": "Gladys",
"what": "Es mi mama",
"kind": "quoteEndpoint#resourcesItem"
},
{
"id": "5639445604728832",
"who": "Carlos",
"what": "Posteando desde el programa",
"kind": "quoteEndpoint#resourcesItem"
}
],
"kind": "quoteEndpoint#resources",
"etag": "\"g5i3Q2SBLLa5w1FcUp586KnA8gM/c_cfE8SxmA5GujJh-tLzNMQGfrg\""
}
我缺少什么,如何获得nextPageToken?
答案 0 :(得分:2)
只有在指定了上一个光标后才会返回光标。如果将null
作为cursorString
传递给端点方法,则不会返回新光标。使用下面的代码返回新的光标值。
//Find the next cursor
Cursor cursor = iterator.getCursor();
if (cursor != null) {
cursorString = cursor.toWebSafeString();
}