我刚开始为 Google App Engine 后端开发 iOS 客户端。我遇到了一个问题,我能够与后端通信但无法将新记录插入数据存储区。
这是后台的代码
@ApiMethod(name = "insertDCustomerRecord")
public DCustomerRecord insertDCustomerRecord(DCustomerRecord dcustomerrecord) {
EntityManager mgr = getEntityManager();
try {
//Object pass in is JSON format, convert to object instance
DCustomerRecord newRecord = new DCustomerRecord(dcustomerrecord.getNRIC(), dcustomerrecord.getContactNumber());
if (containsDCustomerRecord(newRecord)) {
throw new EntityExistsException("Object already exists");
}
mgr.persist(newRecord);
} finally {
mgr.close();
}
return dcustomerrecord;
}
这是ios客户端的代码
- (void) initView {
GRGServiceManager* manager = [GRGServiceManager getInstance];
GTLServiceDcustomerrecordendpoint* service = [manager getDCustomerRecordService];
GTLDcustomerrecordendpointDCustomerRecord* newRecord = [[GTLDcustomerrecordendpointDCustomerRecord alloc] init];
[newRecord setNric:@"1234567A"];
[newRecord setContactNumber:@"12344574"];
GTLQueryDcustomerrecordendpoint* query = [GTLQueryDcustomerrecordendpoint queryForInsertDCustomerRecordWithObject:newRecord];
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLObject *object, NSError *error) {
NSLog(@"Inserted new object");
}];
}
这是实体类
@Entity
public class DCustomerRecord {
/**
* @description this is the primary key of the record, it is auto-generated
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
public Key getId() {
return id;
}
/**
* @description this is to store the NRIC of the customer
*/
private String m_sNRIC;
public String getNRIC() {
if(m_sNRIC == null)
m_sNRIC = "";
return m_sNRIC;
}
public void setNRIC(String nric) {
m_sNRIC = new String(nric);
}
/**
* @description this is to store the contact number of the customer
*/
private String m_sContactNumber;
public String getContactNumber() {
if(m_sContactNumber == null)
m_sContactNumber = "";
return m_sContactNumber;
}
public void setContactNumber(String contact) {
m_sContactNumber = new String(contact);
}
/**
* @description this is to store the number of lucky draw chance this customer has
*/
private Integer m_nNumberOfLuckyDraw;
public int getNumberOfLuckyDraw() {
if(m_nNumberOfLuckyDraw == null)
m_nNumberOfLuckyDraw = 0;
return m_nNumberOfLuckyDraw;
}
public void setNumberOfLuckyDraw(int newNumber) {
m_nNumberOfLuckyDraw = new Integer(newNumber);
}
/**
* @description this is to store the number of passcode redemption this customer has made
*/
private Integer m_nNumberOfPasscodeRedemption;
public int getNumberOfPasscodeRedemption() {
if(m_nNumberOfPasscodeRedemption == null)
m_nNumberOfPasscodeRedemption = 0;
return m_nNumberOfPasscodeRedemption;
}
public void setNumberOfPasscodeRedemption(int newNumber) {
m_nNumberOfPasscodeRedemption = new Integer(newNumber);
}
/**
* @description this is to store the number of photo taken by this customer
*/
private Integer m_nNumberOfPhotoTaken;
public int getNumberOfPhotoTaken() {
if(m_nNumberOfPhotoTaken == null)
m_nNumberOfPhotoTaken = 0;
return m_nNumberOfPhotoTaken;
}
public void setNumberOfPhotoTaken(int newNumber) {
m_nNumberOfPhotoTaken = new Integer(newNumber);
}
/**
* @description this is to store the the time stamp in which the record is created
*/
private Long m_nDateCreated;
public long getDateCreated() {
if(m_nDateCreated == null)
m_nDateCreated = 0L;
return m_nDateCreated;
}
public void setDateCreated(long date) {
m_nDateCreated = new Long(date);
}
/**
* @description this is to store the time stamp is which the record last communicate with server
*/
private Long m_nLastUpdated;
public long getLastUpdated() {
if(m_nLastUpdated == null)
m_nLastUpdated = 0L;
return m_nLastUpdated;
}
public void setLastUpdated(long date) {
m_nLastUpdated = new Long(date);
}
/**
* @description the default constructor
* @param nric - NRIC of the customer
* @param contactNumber - the contact number of the customer
*/
public DCustomerRecord(String nric, String contactNumber) {
//Initialization
setNRIC(nric);
setContactNumber(contactNumber);
setNumberOfLuckyDraw(0);
setNumberOfPasscodeRedemption(0);
setNumberOfPhotoTaken(0);
setDateCreated(System.currentTimeMillis());
setLastUpdated(System.currentTimeMillis());
}
}
错误可能有帮助也可能没有帮助,但这是当我运行连接到后端服务器本地版本的 iOS 应用程序时 Eclipse 控制台中显示的内容。
Aug 16, 2014 7:51:23 PM com.google.api.server.spi.SystemService invokeServiceMethod
INFO: cause={0}
java.lang.NullPointerException
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:318)
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:256)
at com.grg.database.record.DCustomerRecordEndpoint.containsDCustomerRecord(DCustomerRecordEndpoint.java:170)
at com.grg.database.record.DCustomerRecordEndpoint.insertDCustomerRecord(DCustomerRecordEndpoint.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:359)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:160)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:118)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:490)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Aug 16, 2014 7:51:23 PM com.google.api.server.spi.SystemService invokeServiceMethod
SEVERE: null
java.lang.NullPointerException
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:318)
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:256)
at com.grg.database.record.DCustomerRecordEndpoint.containsDCustomerRecord(DCustomerRecordEndpoint.java:170)
at com.grg.database.record.DCustomerRecordEndpoint.insertDCustomerRecord(DCustomerRecordEndpoint.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:359)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:160)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:118)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:490)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
据我所知,该错误是由所有字段都设置为空的 dcustomerrecord 引起的,它被传递到后端服务器中的 insertDCustomerRecord 中。我试过调试服务器,我的假设似乎是正确的。
有没有人遇到过这个问题?任何人都可以帮助解决这个错误吗?我相信我可能在代码中遗漏了一些重要的东西,但我不确定从哪里开始。几天来我一直在谷歌上搜索这个问题,但没有运气。提前致谢!
最佳答案
我没有浪费时间尝试调试问题,而是使用 JSON 对象与 iOS 客户端通信,目前为止运行良好。这不是我在为 Android 和 iOS 开发时遇到的第一个端点库问题。 1 另一个问题是需要编辑端点,特别是插入和包含函数,因为在与 Android 客户端通信时自动生成的代码采用了错误的参数。由于 Google App Engine 不支持 Servlet 3.0,确保必须在 xml 文件的 Servlet-Path 中正确定义每个 servlet 也很麻烦。
在 Google 使他们的端点库“更智能”之前,我强烈建议使用 JSON 传递进行 Google App Engine 开发。
关于iOS 客户端尝试将所有字段设置为 null 的对象插入到本地主机上的端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25339926/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我在破坏脚本的字符串中出现了一些奇怪的字符。据我所知,通过putbadstring到控制台,它们是"\0\0\0\0"。我想对此进行测试,以便我可以忽略它们...但是如何呢?以为这就是blank?和empty?的用途?!?:>badstring="\0"=>"\u0000">badstring.blank?NoMethodError:undefinedmethod`blank?'for"\u0000":Stringfrom(irb):97from/Users/meltemi/.rvm/rubies/ruby-2.0.0-p195/bin/irb:16:in`'>badstring.em
我几天前在我的rubyonrails2.3.2上安装了Sphinx和Thinking-Sphinx,基本搜索效果很好。这意味着,没有任何条件。现在,我想用一些条件过滤搜索。我有公告模型,索引如下所示:define_indexdoindexestitle,:as=>:title,:sortable=>trueindexesdescription,:as=>:description,:sortable=>trueend也许我错了,但我注意到只有当我将:sortable=>true语法添加到这些属性时,我才能将它们用作搜索条件。否则它找不到任何东西。现在,我还在使用acts_as_tag