- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试创建一个与 Google App Engine 交互的 android 应用程序,以在 google 数据存储区中加载和保存实体。我想我的配置是正确的,但我不知道我是否可以上传我的应用程序来测试它,它永远挂起,然后给我这个错误:
SEVERE: Endpoints configuration not updated. The app returned an error when the Google Cloud Endpoints server attempted to communicate with it.
但是,如果我更改版本号,那么即使在收到此消息后,新版本也会在线显示在我的控制台中。我已经阅读了所有关于数据存储的谷歌文档,但无法弄清楚哪里出了问题。我已经遇到这个问题一个月了,一直找不到解决方案。我在某处读到,如果应用程序包含错误,它将不会被上传,所以我将包含我的所有代码。我也不太清楚我在做什么,甚至不确定我是否在正确的轨道上,为什么这不起作用,所以如果你发现任何愚蠢的事情,你应该告诉我。提前谢谢你,如果你能为我解决这个问题,你将成为我的英雄和我的上帝。
这是我的端点:
package com.polo.backend.endpoints;
/**
* Created by sagesmith on 4/16/16.
*
* Is used to interact with the server
*/
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.response.ConflictException;
import com.google.api.server.spi.response.NotFoundException;
import com.googlecode.objectify.Ref;
import com.polo.backend.services.ObjcfyService;
import com.polo.backend.entities.Event;
import com.polo.backend.entities.User;
import java.util.List;
import javax.inject.Named;
/**
*
*/
@Api(
name = "userEndpoint",
version = "v1",
namespace = @ApiNamespace(
ownerDomain = "backend.polo.com",
ownerName = "backend.polo.com",
packagePath = ""
)
)
public class UserEndpoint {
/**
* Registers the two entities used in this class
*/
public UserEndpoint(){
ObjcfyService.register(User.class);
ObjcfyService.register(Event.class);
}
@ApiMethod(name = "insertUser")
/**
* Inserts a new {@code User} into the data store
*/
public void insertUser(User user) throws ConflictException, NotFoundException{
if(getUser(user.getUsername()) != null){
throw new ConflictException("Object already exists");
}
}
/**
*
* @param user
* @throws NotFoundException
*/
@ApiMethod(name = "updateUser")
public void updateUser(User user) throws NotFoundException{
if(getUser(user.getUsername()) != null) {
ObjcfyService.objectify().save().entity(user).now();
}
}
/**
*
* @param username
* @throws NotFoundException
*/
@ApiMethod(name = "removeUser")
public void removeUser(@Named("username") String username) throws NotFoundException{
User record = getUser(username);
if(record != null){
ObjcfyService.objectify().delete().entity(record).now();
}
}
/**
*
* @param username
* @return
* @throws NotFoundException
*/
@ApiMethod(name = "getUser")
public User getUser(@Named("username") String username) throws NotFoundException{
User user = ObjcfyService.objectify().load().type(User.class).id(username).now();
if(user != null) {
List<Ref<User>> friendRefs = user.getFriendRefs();
List<Ref<Event>> repeatingEventRefs = user.getRepeatingEventRefs();
List<Ref<Event>> nonRepeatingEventRefs = user.getNonRepeatingEventRefs();
for (Ref<User> friendRef : friendRefs) {
user.addFriend(friendRef.get());
}
for (Ref<Event> repeatingEventRef : repeatingEventRefs) {
user.addRepeatingEvent(repeatingEventRef.get());
}
for (Ref<Event> nonRepeatingEventRef : nonRepeatingEventRefs) {
user.addNonRepeatingEvent(nonRepeatingEventRef.get());
}
} else{
throw new NotFoundException("User not found");
}
return user;
}
}
这是我的用户实体:
package com.polo.backend.entities;
/**
* Created by sagesmith on 4/16/16.
*/
import com.google.api.server.spi.config.AnnotationBoolean;
import com.google.api.server.spi.config.ApiResourceProperty;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.Load;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@Entity
public class User {
@Id private String username = null;
@Index private String firstName = null;
@Index private String lastName = null;
@Nullable private String status = null;
@Nullable private String location = null;
@Load @Nullable private List<Ref<User>> friendRefs = new ArrayList<>();
@Load @Nullable private List<Ref<Event>> nonRepeatingEventRefs = new ArrayList<>();
@Load @Nullable private List<Ref<Event>> repeatingEventRefs = new ArrayList<>();
@Nullable public List<User> friends = new ArrayList<>();
@Nullable public List<Event> nonRepeatingEvents = new ArrayList<>();
@Nullable public List<Event> repeatingEvents = new ArrayList<>();
/**
*Returns the first name from the {@code User}
*
* @return the first name of the {@code User} as a {@code String}
*/
public String getFirstName(){
return firstName;
}
/**
* Returns the last name from the {@code User}
*
* @return the last name of the {@code User} as a {@code String}
*/
public String getLastName(){
return lastName;
}
/**
* Return the username from the user
*
* @return the username of the user as a String
*/
public String getUsername(){
return username;
}
/**
* Sets the username of the {@code User}
*
* @param username Username to set the {@code User}'s username to
*/
public void setUsername(String username){
this.username = username;
}
/**
* Sets the firstName of the {@code User}
*
* @param firstName First name to set the {@code User}'s first name to
*/
public void setFirstName(String firstName){
this.firstName = firstName;
}
/**
* Sets the lastName of the {@code User}
*
* @param lastName Last name to set the {@code User}'s last name to
*/
public void setLastName(String lastName){
this.lastName = lastName;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a friend to the {@code User}'s list of friends
*
* @param user User to add
*/
public void addFriendRef(User user){
friendRefs.add(Ref.create(user));
}
/**
* Returns the {@code User}'s friends
*
* @return {@code List<Users>} the friends of the {@code User}
*/
public List<User> getFriends(){
return friends;
}
/**
* Adds a friend to the users {@code List} of friends
*
* @param user {@code User} to add as a friend
*/
public void addFriend(User user){
friends.add(user);
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<User>>} of references to the {@code User}'s friends
*
* @return {@code List<Ref<User>>}
*/
public List<Ref<User>> getFriendRefs(){
return friendRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<Event>>} of references to the {@code User}'s repeating
* {@code Event}s
*
* @return {@code List<Ref<Event>>}
*/
public List<Ref<Event>> getRepeatingEventRefs(){
return repeatingEventRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<Event>>} of references to the {@code User}'s non repeating
* {@code Event}s
*
* @return {@code List<Ref<Event>>}
*/
public List<Ref<Event>> getNonRepeatingEventRefs(){
return nonRepeatingEventRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Sets the {@code User}'s status to a given {@code String}
*
* @param status {@code String} to set an {@code Users}'s status to
*/
public void setStatus(String status){
this.status = status;
}
/**
* Returns the {@code User}'s status as a {@code String}
*
* @return {@code String} status
*/
public String getStatus(){
return status;
}
/**
* Returns the {@code User}'s location as a {@code String}
*
* @return {@code String} location
*/
public String getLocation(){
return location;
}
/**
* Sets the {@code User}'s location to a given {@code String}
*
* @param location {@code String} to set an {@code Users}'s location to
*/
public void setLocation(String location){
this.location = location;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a repeating {@code Event} to the {@code User}'s schedule
*
* @param event {@code Event} to add to the {@code User}'s schedule
*/
public void addRepeatingEvent(Event event){
repeatingEventRefs.add(Ref.create(event));
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a non repeating {@code Event} to the user's schedule
*
* @param event Event to add to the the user's schedule
*/
public void addNonRepeatingEvent(Event event){
nonRepeatingEventRefs.add(Ref.create(event));
}
/**
* Returns a {@code List<Event>} of repeating {@code Event}s from the user's schedule
*
* @return List<Event> repeatingEvents from user's schedule
*/
public List<Event> getRepeatingEvents(){
return repeatingEvents;
}
/**
* Returns a list of nonRepeatingEvents from the user's schedule
*
* @return List<Event> repeatingEvents from user's schedule
*/
public List<Event> getNonRepeatingEvents(){
return nonRepeatingEvents;
}
}
和我的事件实体:
package com.polo.backend.entities;
import com.googlecode.objectify.annotation.Entity;
/**
* Created by sagesmith on 5/3/16.
*/
@Entity
public class Event {
private Integer startIndex;
private Integer endIndex;
private Byte[] color;
public Event(Integer startIndex, Integer endIndex, Byte red, Byte green, Byte blue){
this.startIndex = startIndex;
this.endIndex = endIndex;
color = new Byte[]{red, green, blue};
}
}
和我的 ObjectifyService:
package com.polo.backend.services;
/**
* Created by sagesmith on 4/16/16.
*/
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
public class ObjcfyService {
public static void register(Class<?> eClass){
ObjectifyService.register(eClass);
}
public static Objectify objectify(){
return ObjectifyService.ofy();
}
public static ObjectifyFactory objectifyFactory(){
return ObjectifyService.factory();
}
}
这是我的 appengine-web.xml,出于显而易见的原因,我已将我的 appid 替换为 my_id:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>my_id</application>
<version>1</version>
<threadsafe>true</threadsafe>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
这是我的 web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.polo.backend.endpoints.UserEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
最后是我用来从我的 Android 应用程序与数据存储通信的 AsyncTask,我再次用 my_id 替换了我的应用程序 ID:
package com.polo.client;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.polo.StaticAssets;
import com.polo.activity.Home;
import com.polo.backend.userEndpoint.UserEndpoint;
import com.polo.backend.userEndpoint.model.User;
import java.io.IOException;
/**
* Created by sagesmith on 4/17/16.
*/
public class UserAsyncTask extends AsyncTask<Void, Void, User>{
private static UserEndpoint userApiService = null;
private Home context;
private String username;
/**
*
* @param context
*/
public UserAsyncTask(Home context){
this.context = context;
username = StaticAssets.getUserName(context);
}
/**
*
* @param params
* @return
*/
@Override
protected User doInBackground(Void... params){
if(userApiService == null){
UserEndpoint.Builder builder = new UserEndpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(),
null
)
.setRootUrl("https://my_id.appspot.com/_ah/api/");
userApiService = builder.build();
}
User user = null;
try{
user = userApiService.getUser(username).execute();
} catch (IOException e){
Log.e("User not found", e.getMessage());
}
return user;
}
/**
*
* @param result
*/
@Override
protected void onPostExecute(User result) {
if(result!=null)
Toast.makeText(context, result.getFirstName(), Toast.LENGTH_LONG).show();
}
}
最佳答案
它有助于查看建议的完整错误消息:
See the deployment troubleshooting documentation for more information: https://developers.google.com/appengine/docs/java/endpoints/test_deploy#troubleshooting_a_deployment_failure
文档建议首先检查日志中的“/_ah/spi/BackendService.getApiConfigs”。如果我尝试根据示例部署 Endpoints 后端,我会在日志中看到以下内容:
javax.servlet.ServletContext log: unavailable
java.lang.reflect.InvocationTargetException
at com.google.appengine.runtime.Request.process-b693af604777a85a(Request.java)
...
Caused by: java.lang.StackOverflowError
...
com.googlecode.objectify.impl.translate.ClassTranslatorFactory.create(ClassTranslatorFactory.java:49)
...
此错误仅在调用 ObjectifyService.register(class)
时发生, 嗯……
你的 User
里有东西当 Objectify 尝试注册该类并导致 StackOverflowError 时会导致无限递归的类:
@Nullable public List<User> friends = new ArrayList<>();
与其定义一个列表本身,不如定义一个 Ref<User>
的列表来解决这个问题。就像类里面其他地方所做的那样(也许上面是错字):
@Nullable public List<Ref<User>> friends = new ArrayList<>();
此外,另一个问题是由 Event
引起的类缺少一个@Id,它可以如此固定:
@Entity
public class Event {
@Id private Long id;
...
进行这些更改后,我可以毫无错误地部署 Endpoints 应用。
关于java - 无法在 Android Studio 中将 Google Datastore 与 Android App 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37246205/
我正在尝试用我以前的类(class)笔记填充数据存储,以便将来我可以添加评论板或留言簿等笔记。 我似乎无法在数据存储中获取以前的注释,并且一直在翻阅 GAE 文档并在网上搜索无济于事。 这是我的代码:
我得到以下异常: Exception in thread "main" com.google.cloud.datastore.DatastoreException: no matching index
我们有一个在美国和欧盟托管的应用。为了获得出色的性能,我们将在两个位置托管一个数据存储实例。 现在的问题是如何将数据从美国数据存储复制到欧盟数据存储? 或者从技术角度来看,我们将数据存储在哪里并不重要
当我调用 datastore.save 方法时,我偶尔会遇到以下错误: 错误:在/user_code/node_modules/@google-cloud/datastore/node_modules
我正在使用适用于 Datastore (google-cloud-datastore) 版本 1.4.0 的 Python 客户端 SDK。我正在尝试运行仅键查询获取: query = client.
我正在试验 Google App Engine's flexible Python 3 environment and Cloud Datastore .在本地测试时,这(通常)要求在类似 Gunic
Google Cloud Datastore 是否支持计数器等原子操作?我在文档中没有看到任何相关内容,我注意到更新基本上是获取整个对象,更新一个字段,然后将整个对象发送回去,这似乎会使原子操作变得不
我的数据存储实体将具有 embedded entity type 的属性. 在我将它们保存如下后( 我正在使用 gcloud v0.27.0 ): dataset.save([{ key: d
是com.google.cloud.datastore.Datastore线程安全?更具体地说,Datastore 的一个实例可以吗?由多个线程共享,并且它们都可以同时读取/写入云数据存储吗? 换句话
Cloud Dataflow页面暗示这是可能的,但我还没有在 Google Cloud Datastore 文档中找到观察更改事件的方法。它是如何完成的? 最佳答案 据我所知,Cloud Datast
Google Cloud Firestore 将很快取代旧的 Google Cloud Datastore。然后可以选择在“ native 模式”或“数据存储模式”下使用 Cloud Firestor
我是 Datastore 的新手,我正在尝试创建一个简单的应用程序来跟踪图书借阅情况。 我希望数据库架构如下: books: book_id name: borrowing: time
这个问题已经被回答过很多次了,但答案似乎总是在变化。 我正在使用 Java 在 Windows 中工作,并且有一个本地数据存储实例,我希望将其作为生产的副本。 之前有两个答案:- How to cre
如何通过 Google Cloud Datastore 中的 API(Python Protocol Buffer )删除整个祖先树? 例如,如果我将实体存储在此结构中:祖父/父/子,我如何删除祖父,
我想在 Google Cloud Datastore(Datastore 模式下的 Firestore)中保存一部分结构。 以电话簿和联系人为例。 type Contact struct { Ke
我正在尝试看看仅使用 Cloud Functions 与 Datastore 交互是否可行。 有没有一种方法可以仅使用 Cloud Functions 创建复合索引(如 index.yaml)?因此只
我注册了 Firebase 以使用新的 Firestore。 尝试后,我决定,对于我的用例(主要是服务器工具),我不需要 Firestore 的大部分功能,这些功能非常专注于构建用户界面,而且我发现旧
我目前正在使用一台按顺序运行并从命名空间中读取实体的机器执行迁移,这对我来说很痛苦。是否可以使用 Google Cloud Dataflow 更轻松地执行迁移? 最佳答案 您应该能够使用 Datast
我想在 MongoDB 中使用 Grails2.5 中的“ElasticSearch”插件。我的“BuildConfig.groovy”文件是: grails.servlet.version = "3
我想从 Rails 应用程序中使用 Google Cloud Datastore。任何 Ruby 库都可以让这一切变得简单? 最佳答案 您可以使用官方的 Google API Client for R
我是一名优秀的程序员,十分优秀!