Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 4

0
votes
answers
78 views
+10

從谷歌應用程序引擎(春季啓動應用程序)無法連接到谷歌雲的SQL(第二代)

0

最近一直讓我瘋狂,希望任何人都可以幫助我。從谷歌應用程序引擎(春季啓動應用程序)無法連接到谷歌雲的SQL(第二代)

我一直試圖從谷歌應用程序引擎(春季啓動應用程序)連接到谷歌雲(第二代),但沒有運氣。我按照此頁上的說明https://cloud.google.com/appengine/docs/flexible/java/using-cloud-sql獲取連接字符串。從我的本地計算機連接到谷歌雲sql是很好的。

此外,我的應用程序引擎和谷歌sql實例來自同一個項目。我也驗證了我可以連接到谷歌SQL從谷歌應用程序引擎的雲殼

我想知道哪個是正確的連接字符串使用。我想這兩個連接模板,但沒有得到任何運氣

  • 「的jdbc:谷歌的:mysql:// $ {INSTANCE_CONNECTION_NAME}/$ {}數據庫用戶= $ {}用戶密碼& = $ {}密碼? 「

  • 」 的jdbc:mysql的://谷歌/ $ {}數據庫= useSSL假& cloudSqlInstance = $ {} INSTANCE_CONNECTION_NAME &的SocketFactory = com.google.cloud.sql.mysql.SocketFactory &用戶= $ {用戶} & password = $ {password}「

這是從谷歌雲日誌跡:

017-11-17 00:20:51 default[20171117t071753]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131] 

2017年11月17日0時20分五十一秒默認[20171117t071753]所致:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信鏈路失敗 2017-11-17 00:20:51默認[20171117t071753] 2017-11-17 00:20:51默認[20171117t071753]成功發送到服務器的最後一個數據包是0毫秒前。驅動程序尚未收到來自服務器的任何數據包。 2017-11-17 00:20:51默認[20171117t071753] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)?[na:1.8.0_131] 2017-11-17 00:20:51默認[20171117t071753] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)?[na:1.8.0_131] 2017-11-17 00:20:51 default [20171117t071753] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java :45)?[na:1.8.0_131] 2017-11-17 00:20:51默認[20171117t071753] at java.lang.reflect.Constructor.newInstance(Constructor.java:423)?[na:1.8.0_131 ] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)?[mysql-connector-java-5.1.43.jar!/:5.1 .43] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc.SQLError.createC ommunicationsException(SQLError.java:989)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc。 MysqlIO。(MysqlIO.java:341)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc .ConnectionImpl.coreConnect(ConnectionImpl.java:2196)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql .jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2229)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51 default [20171117t071753] at com .mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2024)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51 default [20171117t071753]在com.mysql.jdbc.ConnectionImpl。(ConnectionImpl.java:779)?[mysql-connector-java-5.1.43。 jar!/:5.1.43] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc.JDBC4Connection。(JDBC4Connection.java:47)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51 default [20171117t071753] at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Native Method)?[na:1.8.0_131] 2017-11-17 00:20:51 default [20171117t071753] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)?[na:1.8.0_131] 2017-11-17 00:20:51默認[20171117t071753] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)?[na:1.8.0_131] 2017-11-17 00:20:51 default [20171117t071753] at java.lang.reflect.Constructor.newInstance(Constructor.java:423)?[na:1.8.0_131] 2017-11-17 00:20:51默認[20171117t071753] at com.mysql.jdbc。 Util.handleNewInstance(Util.java:425)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-1 7 00:20:51 default [20171117t071753] at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:389)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017- 11-17 00:20:51 default [20171117t071753] at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)?[mysql-connector-java-5.1.43.jar!/:5.1.43] 2017-11-17 00:20:51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:310)?[tomcat-jdbc-8.5.16.jar!/:na ] 2017-11-17 00:20:51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203)?[tomcat-jdbc-8.5.16.jar!/ :na] 2017-11-17 00:20:51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735)?[tomcat-jdbc-8.5.16.jar !/:na] 2017-11-17 00:20:51預設[20 171117t071753] at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11-17 00:20:51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11-17 00:20 :51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.ConnectionPool。(ConnectionPool.java:154)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11-17 00: 20:51 default [20171117t071753] at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11-17 00:20:51默認[20171117t071753] at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11 -17 00:20:51默認[20171117t071753]位於org.apache.tomcat.jdbc.pool.DataSourc eProxy.getConnection(DataSourceProxy.java:131)?[tomcat-jdbc-8.5.16.jar!/:na] 2017-11-17 00:20:51默認[20171117t071753]位於org.springframework.jdbc.datasource。 DataSourceUtils.doGetConnection(DataSourceUtils.java:111)?[spring-jdbc-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 2017-11-17 00:20:51默認[20171117t071753] at org。 springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)?[spring-jdbc-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 2017-11-17 00:20:51 default [20171117t071753] ... 29個常見框架遺漏 2017-11-17 00:20:51默認[20171117t071753]由java.net.UnknownHostException造成:google.net.InetAddress.getAllByName0(InetAddress.java:1280) ?[na:1.8.0_131] at java.net.InetAddress.getAllByName(InetAddress.java:1192)?[na:1.8.0_131] at java.net.InetAddress.getAllByName(InetAddress.java:1126)?[na: 1.8.0_131]在com.mysq l.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:188)?[mysql-connector-java-5.1.43.jar!/:5.1.43] at com.mysql.jdbc.MysqlIO。(MysqlIO.java:300) ?[mysql-connector-java-5.1.43.jar!/:5.1.43]

沙发
0
0

在我的應用程序屬性中,我使用jdbc:mysql:// [host]:[port]/[dbname]?autoReconnect = true &對於url屬性,useSSL = false並且工作正常。

但在我看來,你的錯誤是由於你必須在你的cloud-sql實例的授權部分授權你的app-engine的IP地址。

Configuring IP Access on Cloud SQL instance

+0

謝謝帕夫勒花時間回答這個問題。你提到的是,如果我們從外部環境連接到cloud-sql。 此外,我只是想出了我做錯了什麼,我們必須將包裝設置爲war而不是jar,並添加appengine-web.xml以將use-google-connector-j設置爲true,這將指示Google引擎使用谷歌連接器而不是mysql連接器 – TruongNguyen

+0

很酷。我很高興你解決了這個問題。 –

+0

這是不正確的建議。從App Engine進行連接時,不應使用IP連接,而應使用App Engine特定的連接,如下所述:https://cloud.google.com/sql/docs/mysql/connect-app-engine。 – Vadim

0
votes
answers
50 views
+10

配額在開發環境終點框架v2和部署項目

0

症狀配額在開發環境終點框架v2和部署項目

我開發服務器上工作,但在部署到GCP的響應是一個新的標準環境終點框架(V2)項目:應用程序暫時超過其服務配額。請稍後再試。

但是,如果我嘗試添加配額限制和指標(根據https://cloud.google.com/endpoints/docs/frameworks/quotas-configure),則開發服務器錯誤爲:AttributeError:'tuple'對象沒有屬性'metric_name'。

下面是完整的錯誤記錄。我懷疑有關oauth2client的警告與配額問題無關,但與當前的端點模塊有關。

該錯誤似乎指向limit_definitions,但這些來自Google示例。

代碼片段:

quota_limits = [ 
    ("read-requests", "Read Requests", 1000), 
    ("list-requests", "List Requests", 100), 
    ("write-requests", "Write Requests", 50), 
] 

@endpoints.api(
    name='echo', 
    version='v1', 
    limit_definitions=quota_limits, 

問:
如何,我不是:不使用配額或正確配置配額?還是有錯誤?顯示 gcloud信息

Google Cloud SDK [180.0.0] 

Platform: [Linux, x86_64] ('Linux', 'host-name', '4.4.0-98-generic', '#121-Ubuntu SMP Tue Oct 10 14:24:03 UTC 2017', 'x86_64', 'x86_64') 
Python Version: [2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]] 
Python Location: [/usr/bin/python2] 
Site Packages: [Disabled] 

Installation Root: [/home/steve/google-cloud-sdk] 
Installed Components: 
    core: [2017.11.10] 
    app-engine-python: [1.9.63] 
    gcloud: [] 
    beta: [2017.09.15] 
    gsutil: [4.28] 
    cloud-datastore-emulator: [1.3.0] 
    bq: [2.0.27] 
System PATH: [/home/steve/google-cloud-sdk/bin:/home/steve/.nvm/versions/node/v6.11.1/bin:/home/steve/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin:/home/steve/google-cloud-sdk/platform/google_appengine:/home/steve/Android/Sdk/tools:/home/steve/Android/Sdk/tools/bin:/home/steve/Android/Sdk/platform-tools:~/bin:~/.config/yarn/global/node_modules/.bin] 
Python PATH: [/home/steve/google-cloud-sdk/lib/third_party:/home/steve/google-cloud-sdk/lib:/usr/lib/python2.7/:/usr/lib/python2.7/plat-x86_64-linux-gnu:/usr/lib/python2.7/lib-tk:/usr/lib/python2.7/lib-old:/usr/lib/python2.7/lib-dynload] 
Cloud SDK on PATH: [True] 
Kubectl on PATH: [False] 
There are alternate versions of the following Google Cloud Platform tools on your system PATH. 
    /home/steve/google-cloud-sdk/platform/google_appengine/dev_appserver.py 
    /home/steve/google-cloud-sdk/platform/google_appengine/endpointscfg.py 

Installation Properties: [/home/steve/google-cloud-sdk/properties] 
User Config Directory: [/home/steve/.config/gcloud] 
Active Configuration Name: [default] 
Active Configuration Path: [/home/steve/.config/gcloud/configurations/config_default] 

Account: [<removed-for-public-post>] 
Project: [project-name] 

Current Properties: 
    [core] 
    project: [project-name] 
    account: [<removed for public post>] 
    disable_usage_reporting: [False] 

Logs Directory: [/home/steve/.config/gcloud/logs] 
Last Log File: [/home/steve/.config/gcloud/logs/2017.11.18/11.00.31.517561.log] 

git: [git version 2.7.4] 
ssh: [OpenSSH_7.2p2 Ubuntu-4ubuntu2.2, OpenSSL 1.0.2g 1 Mar 2016] 

完整的錯誤:

SDK

WARNING 2017-11-18 05:57:18,958 multistore_file.py:62] The oauth2client.contrib.multistore_file module has been deprecated and will be removed in the next release of oauth2client. Please migrate to multiprocess_file_storage. 
ERROR 2017-11-18 05:57:19,080 wsgi.py:263] 
Traceback (most recent call last): 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle 
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler()) 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler 
    handler, path, err = LoadObject(self._handler) 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject 
    obj = __import__(path[0]) 
    File "/home/steve/gae/prototyping/endpoint+fbauth/main.py", line 35, in <module> 
    'https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]')} 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/lib/protorpc-1.0/protorpc/util.py", line 173, in positional_wrapper 
    return wrapped(*args, **kwargs) 
    File "/home/steve/gae/prototyping/endpoint+fbauth/lib/endpoints/api_config.py", line 1038, in api 
    limit_definitions=limit_definitions) 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/lib/protorpc-1.0/protorpc/util.py", line 173, in positional_wrapper 
    return wrapped(*args, **kwargs) 
    File "/home/steve/gae/prototyping/endpoint+fbauth/lib/endpoints/api_config.py", line 508, in __init__ 
    base_path=base_path, limit_definitions=limit_definitions) 
    File "/home/steve/google-cloud-sdk/platform/google_appengine/lib/protorpc-1.0/protorpc/util.py", line 173, in positional_wrapper 
    return wrapped(*args, **kwargs) 
    File "/home/steve/gae/prototyping/endpoint+fbauth/lib/endpoints/api_config.py", line 601, in __init__ 
    _CheckLimitDefinitions(limit_definitions) 
    File "/home/steve/gae/prototyping/endpoint+fbauth/lib/endpoints/api_config.py", line 243, in _CheckLimitDefinitions 
    if not ld.metric_name: 
AttributeError: 'tuple' object has no attribute 'metric_name' 
沙发
0
0

quota_limits需求是endpoints.api_config.LimitDefinition實例,而不是一個元組的列表清單。這是文檔中的錯誤;我會確保它們得到糾正,並且我會改進錯誤信息以便更清楚。

0
votes
answers
77 views
+10

我是否需要在Google App Engine後面設置反向代理?

1

我在Google App engine上運行我的應用程序,並且我已將從GoDaddy購買的domain連同我從GoDaddy購買的SSL連接到應用程序引擎。我是否需要在Google App Engine後面設置反向代理?

我在很多運行port 80服務器的站點上讀到它,而沒有Reverse Proxy會導致您的主要安全問題。但我看不到他們在談論哪些問題。另外,因爲我在port 5555上運行我的應用程序,我甚至試圖ping我的域名,IP爲216.239.XX.21,其中X可能的值可以是(32, 34, 36 and 38),這與所有其他App Engine服務器相同。所以我認爲,如果有任何hacker/malicious用戶試圖對我的應用程序進行惡意操作,那麼爲了做到這一點,他/她必須知道我的IP,其中App Engine默認隱藏。

所以,我想知道作爲App Engine已經隱藏我的IP所以我必須對我的App Engine或不使用任何Reverse Proxy ServerNginx

此外,如果我需要使用Reverse Proxy那麼我看到這兩個帖子nginx-as-reverse-proxy-for-google-app-engine-applicationusing-nginx-as-a-reverse-proxy-for-speedy-app-engine-development/

在第一篇文章中,它是not建議使用Reverse Proxy而在第二篇文章中,建議使用Reverse Proxy。這讓我感到困惑,這將是更好的方法。

請幫我個個。

沙发
0
2

在Google羣組上發佈這個問題後,他們告訴我,無需爲靈活和標準環境設置反向代理。在標準環境1

  • App Engine的情況下,不具備公共靜態IP地址,並通過主 谷歌前端服務器被完全保護。首先請求您的應用程序訪問Google前端 ,然後前端根據您上傳的證書[2]執行SSL安全檢查 ,然後使用其內部IP將 請求轉發給您的App Engine實例。 因此不需要反向代理。

  • 如果您使用的是App Engine靈活環境[3],您可以使用計算引擎 VM [4]爲您的實例提供靜態IP。但是,App Engine會自動在預先配置的每個App Engine Flexible實例前加載Nginx代理,因此您根本沒有 進行設置。您只需按照 上傳您的SSL證書[5]的指南操作,並且請求將由Google 前端審覈,就像上面的標準環境一樣。因此,不需要添加 反向代理。

完整的答案可以在這裏找到issue

0
votes
answers
77 views
+10

如何重命名數據存儲實體字段,但能夠通過舊的和新的屬性名稱檢索記錄?

0

我有一個實體如何重命名數據存儲實體字段,但能夠通過舊的和新的屬性名稱檢索記錄?

class Foo { 
    public String bar; 
} 

我想重命名 「酒吧」 到 「somethingElse」。並計劃使用Objectify的@AlsoLoad註解來實現這一點(我已經在使用Objectify進行持久化)。因此,像:

class Foo { 
    @AlsoLoad("bar") 
    public String somethingElse; 
} 

但形式有任何疑問:

final Query<Foo> query = OfyService.ofy().load().type(Foo.class) 
    .filter("somethingElse", "someValue"); 

只擷取自重命名已保存的實體。任何較舊的實體都被忽略。

什麼是重命名實體字段的最佳做法,以便我可以有一個將返回所有記錄的單個查詢?

沙发
0
3

注意:我不是一個客觀化的用戶,答案是通用的,所以你必須適應物化的細節。

一般要避免同時使用barsomethingElse爲長時間,主要是因爲尋找匹配實體轉化爲OR類型的查詢 - .filter("bar", "someValue")OR.filter("somethingElse", "someValue"),這是由數據存儲不支持的根本。從Restrictions on queries

NOTOR!=運營商本身不支持, 但有些客戶端庫可以在雲存儲上添加支持。

這意味着,在最好的,你必須跳火圈,使這樣的工作,例如見,Google Datastore combine (union) multiple sets of entity results to achieve OR condition

我的建議是進行一次性遷移,並用它完成。這將包括以下步驟:

  • 最有可能的,你必須有在遷移過程中性能配置/活着,所以不只是重命名bar,而不是添加somethingElse不要立即刪除bar
  • 在所有的地方,你更新bar屬性還更新somethingElse相應
  • 添加邏輯來查詢具有bar但沒有somethingElse並把它們重新寫那麼他們也有所有實體3210。這一步完成後,所有的實體應該有一個somethingElse鏡像bar在你讀bar的價值交換閱讀somethingElse代替
  • 檢查含somethingElse所有索引服務於所有非查詢的地方
  • ,然後換你的查詢從barsomethingElse。有了這個實際的遷移已完成,您可以執行以下
  • 降清理步驟寫bar財產
  • 執行查詢對具有bar屬性的所有entitites並把它們重新寫不bar。請注意,這可能比真正從模型和指標讓這些實體單獨
  • 下降bar(如果適用於您的客戶端庫)更貴,但只有當你在上一步中刪除了所有的實體財產

此方法的遷移可以緩慢執行,因爲它不需要完全關閉服務,因此可以通過live進行遷移。

+0

謝謝丹。我得出了同樣的結論。 – William

0
votes
answers
72 views
+10

我想從JSON數據,我從HttpURLConnection的得到實現的TextView

-3
//[(START)File:ThirdActivity.java] --> 
package com.example.caleb.splash_screen; 

import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 
import java.io.*; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.io.IOException; 
import java.io.OutputStream; 


public class ThirdActivity extends AppCompatActivity { 
    //public String text = "https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt"; 


    public TextView text; 

    private void writeStream(OutputStream out){ 
     String output = "Hello world"; 

     // out.write(output.getBytes()); 
     //out.flush(); 
    } 


    /*private String readStream(InputStream is) { 
     try {`enter code here` 
      ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
      int i = is.read(); 
      while(i != -1) { 
       bo.write(i); 
       i = is.read(); 
      } 
      return bo.toString(); 
     } catch (IOException e) { 
      return ""; 
     } 
    }*/ 

    //[(START) readStream --> 
    private String readStream(InputStream in) throws IOException { 
    BufferedReader bin = new BufferedReader(new InputStreamReader(in)); 
    //temporary 
     try { 
      StringBuilder sb = new StringBuilder(); 
      String inputLine; 
      while ((inputLine = bin.readLine()) != null) { 
       sb.append(inputLine); 
      } 
      return sb.toString(); 


     } finally { 

     } 
    } 
    //[(END) readStream --> 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_third2); 

     text = (TextView)findViewById(R.id.textView); 

     new JSONTask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt"); 

    } 

} 
//[(END)File:ThirdActivity] --> 







//[(START)File:JSONTask] --> 

package com.example.caleb.splash_screen; 

import android.app.Activity; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.support.v4.widget.TextViewCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.widget.TextView; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 

/** 
* Created by Caleb on 12/17/2017. 
*/ 

public class JSONTask extends AsyncTask<String,String,String> { 


//final TextView txt = (TextView)findViewById(R.id.textView); 
    private Context context; 

    public JSONTask(Activity ThirdActivity) { 
     context = ThirdActivity; 
    } 

@Override 
    protected String doInBackground(String... params) { 
     BufferedReader reader = null; 
     HttpURLConnection urlConnection = null; 
     //{(START)] Working Connection:ALERT! Error within code will cause crash --> 
     try { 
      URL url = new URL(params[0]); 
      Log.w("testing", "test"); 
      urlConnection = (HttpURLConnection) url.openConnection(); 
      urlConnection.setRequestMethod("GET"); 
      urlConnection.setDoOutput(false); 
      urlConnection.connect(); 
      //urlConnection.setChunkedStreamingMode(0); 
      //OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); 
      //writeStream(out); 
      /*int a = urlConnection.getResponseCode(); 
      String b = String.valueOf(a); 
      Log.e(b, "yesssssssssssssssss");*/ 

      InputStream in = urlConnection.getInputStream(); 
      //InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 
      reader = new BufferedReader(new InputStreamReader(in)); 
      StringBuffer buffer = new StringBuffer(); 
      String line = ""; 
      while ((line = reader.readLine()) != null) { 
       buffer.append(line); 
      } 
      /*String data = readStream(in); 
      /*final TextView textView = (TextView) findViewById(R.id.textView); 
      textView.setText("hello"); 
      */ 

      return buffer.toString(); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 

     } finally { 
      if (urlConnection != null) { 
       urlConnection.disconnect(); 
      } 
      try { 
       if (reader != null) { 
        reader.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     //{(END)] Working Connection --> 
     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     TextView text = (TextView) ((AppCompatActivity) context).findViewById(R.id.textView); 
     text.setText(result); 

    } 

} 
//[(END)File:JSONTask] --> 

/預期的效果/我想從JSON數據,我從HttpURLConnection的得到實現的TextView

塊引用

我想從JSON中提取數據文件指出url指向並更改UI中稱爲textView的TextView。我不明白如何訪問AsyncTask中的findviewbyid。我看了所有整個互聯網,但沒有找到任何東西:(任何建議都非常感謝!

沙发
0
0

嘗試弱引用獲得的TextView中的AsyncTask

//調用異步任務

new JSONTask(yourTextView).execute(); 

//你的異步任務

private final WeakReference<TextView> textViewReference; 

    public JSONTask (TextView textView){ 
     textViewReference = new WeakReference<TextView>(textView); 
    } 


    @Override 
    protected void onPostExecute() { 


      TextView textView = textViewReference.get(); 
      //set values to text view 

    } 
板凳
0
0

我使用OkHttp做同樣的任務,我的應用程序

  • HTTP/2支持允許對同一主機的所有請求共享一個套接字。

  • 連接池減少了請求延遲(如果HTTP/2不可用)。

  • 透明GZIP縮小下載大小。

  • 響應緩存避免網絡完全重複請求。

添加這種依賴性

implementation 'com.squareup.okhttp3:okhttp:3.9.1' 

然後創建/代碼名爲新類OkHttpHandler

class OkHttpHandler extends AsyncTask<String, String, String> { 

     OkHttpClient client = new OkHttpClient(); 
     private volatile String data; 

     public String getResult() { 
      return data; 
     } 

     @Override 
     protected String doInBackground(String... params) { 

      try { 
       Request.Builder builder = new Request.Builder(); 
       builder.url(params[0]); 
       Request request = builder.build(); 

       Response response = client.newCall(request).execute(); 
       return response.body().string(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      data = s; 
     } 
    } 
} 

,並使用它像這樣

String str = new OkHttpHandler().execute("http://www.<TEST>.com/json").get(); 

我也建議檢查Wi-fi-Connected/Bluetooth-ConnectedPhoneData-Enabled是否if真正 /否則,繼續你的代碼

0
votes
answers
48 views
+10

在PyCharm .idea文件夾中更改時防止App引擎熱重新加載

0

每當文件發生更改時,App Engine本地開發服務器都會重新加載 - 這很酷。什麼是不酷的是,它還重新加載PyCharm編輯器的.idea文件夾中的更改,使日誌混亂。試圖將此添加到app.yaml skip_files: - ^(.*/)?#.*#$ - ^(.*/)?.*~$ - ^(.*/)?.*.py[co]$ - ^(.*/)?.*/RCS/.*$ - ^(.*/)?..*$ - ^.idea$ # added this line in order to try and ignore .idea folder on build 在PyCharm .idea文件夾中更改時防止App引擎熱重新加載

這沒有幫助。每次我在編輯器中做任意東西時都會重建(不更改任何代碼)。

如何告知App Engine dev服務器要忽略熱重載的文件夾?

+0

嘗試「^ 。idea * $」也許吧? –

沙发
0
0

dev_appserver.py --help提到:

--watcher_ignore_re WATCHER_IGNORE_RE 
         Regex string to specify files to be ignored by the 
         filewatcher. (default: None) 

在這種情況下,這是關係到dev_appserver.py,這將檢測本地app.yaml更改並重新加載本地服務器,而app.yaml在GAE運行的是不應該這樣做,因爲重裝被做gcloud app deploy

+0

這看起來完全像我所需要的,除了它不工作的事實。提供了我能想到的任何可能的表達方式 - 無效。事件試過'。*'像往常一樣工作(不會忽略任何東西)。 – MeLight

+0

你使用的是什麼版本? [resent版本](https://github.com/GoogleCloudPlatform/python-compat-runtime/blob/743ade7e1350c790c4aaa48dd2c0893d06d80cee/appengine-compat/exported_appengine_sdk/google/appengine/tools/devappserver2/watcher_common.py#L71)似乎忽略了所有以點開頭的文件(_IGNORED_PREFIX =='。')。 –

+0

該鏈接導致了現在稱爲「靈活環境」的棄用版本。我正在使用標準環境。 – MeLight

0
votes
answers
70 views
+10

如何使用Google App Engine中的特定關鍵字獲取結果在Java中使用NO-SQL數據存儲區查詢?

0

我們使用GoogleInfo表,在該表中,我們存儲了應用程序的範圍。例如「https://www.googleapis.com/auth/drive.appdata,https://www.googleapis.com/auth/drive.file」 ,並且我試圖根據某個關鍵字(例如範圍內的「drive」)獲取結果,並根據該關鍵字獲得結果。以下是我的代碼。請建議。如何使用Google App Engine中的特定關鍵字獲取結果在Java中使用NO-SQL數據存儲區查詢?

String keywords[] = {"admin","drive","gmail","userinfo"}; 

Query query = pm.newQuery("SELECT scopes FROM com.cloudcodes.gcontrol.dataaccesslayer.insights.google.drive.GoogleInfo where :p.contains(scopes)"); 

result = (List) query.execute(Arrays.asList(keywords)); 
List tempResult = new ArrayList(); 
tempResult.addAll(result); 
return tempResult; 
沙发
0
0

似乎你正在使用JDO [1]和PersistanceManager [2]。

就我所見,您嘗試執行的查詢可能是錯誤的。檢查如何使用JDO執行查詢[3]。

您所查詢的是:

String keywords[] = {"admin","drive","gmail","userinfo"}; 
Query query = pm.newQuery("SELECT scopes FROM com.cloudcodes.gcontrol.dataaccesslayer.insights.google.drive.GoogleInfo where :p.contains(scopes)"); 
result = (List) query.execute(Arrays.asList(keywords)); 

看起來你想要做的事,如:

//Query for all persons with lastName equal to Smith or Jones 
Query q = pm.newQuery(Person.class, ":p.contains(lastName)"); 
q.execute(Arrays.asList("Smith", "Jones")); 
Person.class is the kind 
Arrays.asList("Smith", "Jones") 

此參數 「:p.contains(lastName的)」 定義lastName的是我們想要的屬性檢查。 您正在將該類設置爲com.cloudcodes.gcontrol.dataaccesslayer.insights.google.drive.GoogleInfo,我想這是完整的Java名稱包,其中的類習慣是類名,而類名是GoogleInfo。所以你可以嘗試:

Query q = pm.newQuery(GoogleInfo.class, ":p.contains(scopes)"); 
q.execute(Arrays.asList("admin","drive","gmail","userinfo")); 

你想檢索範圍。我假設你想使用REST API。所以在裏面:p.contains(「scopes」)可能會去與您想要檢索的實體中的keyWords相關的另一個屬性,也許是數組屬性?

在這裏,我與大家分享一些可能有用的文檔[4] [5]。

希望這會有所幫助!

[1] https://cloud.google.com/appengine/docs/standard/java/datastore/jdo/overview-dn2

[2] http://massapi.com/method/javax/jdo/PersistenceManager.newQuery-4.html

[3] https://cloud.google.com/appengine/docs/standard/java/datastore/jdo/queries

[4] https://cloud.google.com/datastore/docs/concepts/overview#comparison_with_traditional_databases

[5] https://cloud.google.com/datastore/docs/reference/gql_reference

0
votes
answers
59 views
+10

GAE地區 - 確切位置

1

我的GAE(標準)應用程序位於歐洲西部地區。GAE地區 - 確切位置

我正在研究創建支持此應用程序的Cloud SQL實例,並且希望將它放在最接近GAE的位置。

目前的雲SQL實例可在以下位置: 歐洲west1比利時 歐洲west2倫敦 歐洲west3法蘭克福

有沒有辦法找出我的GAE應用程序的其它位置的詳細信息,以決定使用哪個雲SQL位置?

沙发
0
2

您可以使用雲殼中的gcloud app describe來查找您的應用的位置信息。鍵入此命令(gcloud應用描述)在外殼的回報是這樣的:

authDomain: gmail.com 
codeBucket: staging.my-project-id.appspot.com 
defaultBucket: my-project-id.appspot.com 
defaultHostname: my-project-id.appspot.com 
featureSettings: 
    splitHealthChecks: true 
gcrDomain: eu.gcr.io 
id: my-project-id 
locationId: europe-west2 
name: apps/my-project-id 
servingStatus: SERVING 

看到命令描述here

接下來,您可以通過輸入gcloud sql instances create [your-instance-name] --region=[region-of-your-choice]來創建SQL實例。例如:

[email protected]:~$ gcloud sql instances create test-instance --region=europe-west2 
Creating Cloud SQL instance...done. 
Created [https://www.googleapis.com/sql/v1beta4/projects/my-project-id/instances/test-instance]. 
NAME   DATABASE_VERSION REGION  TIER    ADDRESS   STATUS 
test-instance MYSQL_5_6   europe-west2 db-n1-standard-1 00.000.000.000 RUNNABLE 
[email protected]:~$ 

所有可用的選項是here

0
votes
answers
80 views
+10

跨源請求阻止 - 創建實體GAE數據存儲

0

我下面這個谷歌火力地堡教程:https://cloud.google.com/appengine/docs/standard/python/authenticating-users-firebase-appengine跨源請求阻止 - 創建實體GAE數據存儲

我在最後一部分地方增加了注到數據存儲,但是當我按下按鈕來添加筆記它不會做任何事情,並給我在Firefox Web控制檯中的以下錯誤:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://backend-dot-i7643225firenotes.appspot.com/notes. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). 

任何想法是什麼原因造成這種情況?我沒有觸及Google提供的代碼,但無論如何我都會加入它。它的其餘部分可以在這裏找到:

https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/standard/firebase/firenotes

main.js

// Copyright 2016, Google, Inc. 
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License. 

$(function(){ 
    // This is the host for the backend. 
    // TODO: When running Firenotes locally, set to http://localhost:8081. Before 
    // deploying the application to a live production environment, change to 
    // https://backend-dot-<PROJECT_ID>.appspot.com as specified in the 
    // backend's app.yaml file. 
    var backendHostUrl = 'https://backend-dot-i7643225firenotes.appspot.com'; //localhost:8081 

    // Initialize Firebase 
    // TODO: Replace with your project's customized code snippet 
    var config = { 
    apiKey: "REMOVED", 
    authDomain: "REMOVED", 
    databaseURL: "https://<DATABASE_NAME>.firebaseio.com", 
    storageBucket: "<BUCKET>.appspot.com", 
    }; 

    // This is passed into the backend to authenticate the user. 
    var userIdToken = null; 

    // Firebase log-in 
    function configureFirebaseLogin() { 

    firebase.initializeApp(config); 

    // [START onAuthStateChanged] 
    firebase.auth().onAuthStateChanged(function(user) { 
     if (user) { 
     $('#logged-out').hide(); 
     var name = user.displayName; 

     /* If the provider gives a display name, use the name for the 
     personal welcome message. Otherwise, use the user's email. */ 
     var welcomeName = name ? name : user.email; 

     user.getToken().then(function(idToken) { 
      userIdToken = idToken; 

      /* Now that the user is authenicated, fetch the notes. */ 
      fetchNotes(); 

      $('#user').text(welcomeName); 
      $('#logged-in').show(); 

     }); 

     } else { 
     $('#logged-in').hide(); 
     $('#logged-out').show(); 

     } 
    // [END onAuthStateChanged] 

    }); 

    } 

    // [START configureFirebaseLoginWidget] 
    // Firebase log-in widget 
    function configureFirebaseLoginWidget() { 
    var uiConfig = { 
     'signInSuccessUrl': '/', 
     'signInOptions': [ 
     // Leave the lines as is for the providers you want to offer your users. 
     firebase.auth.GoogleAuthProvider.PROVIDER_ID, 

     //firebase.auth.FacebookAuthProvider.PROVIDER_ID, 
     //firebase.auth.TwitterAuthProvider.PROVIDER_ID, 
     //firebase.auth.GithubAuthProvider.PROVIDER_ID, 

     firebase.auth.EmailAuthProvider.PROVIDER_ID 
     ], 
     // Terms of service url 
     'tosUrl': '<your-tos-url>', 
    }; 

    var ui = new firebaseui.auth.AuthUI(firebase.auth()); 
    ui.start('#firebaseui-auth-container', uiConfig); 
    } 
    // [END configureFirebaseLoginWidget] 

    // [START fetchNotes] 
    // Fetch notes from the backend. 
    function fetchNotes() { 
    $.ajax(backendHostUrl + '/notes', { 
     /* Set header for the XMLHttpRequest to get data from the web server 
     associated with userIdToken */ 
     headers: { 
     'Authorization': 'Bearer ' + userIdToken 
     } 
    }).then(function(data){ 
     $('#notes-container').empty(); 
     // Iterate over user data to display user's notes from database. 
     data.forEach(function(note){ 
     $('#notes-container').append($('<p>').text(note.message)); 
     }); 
    }); 
    } 
    // [END fetchNotes] 

    // [START signOutBtn] 
    // Sign out a user 
    var signOutBtn =$('#sign-out'); 
    signOutBtn.click(function(event) { 
    event.preventDefault(); 

    //FirebaseAuth.getInstance().signOut(); 
    firebase.auth().signOut().then(function() { 
     console.log("Sign out successful"); 
    }, function(error) { 
     console.log(error); 
    }); 
    }); 
    // [END signOutBtn] 

    // [START saveNoteBtn] 
    // Save a note to the backend 
    var saveNoteBtn = $('#add-note'); 
    saveNoteBtn.click(function(event) { 
    event.preventDefault(); 

    var noteField = $('#note-content'); 
    var note = noteField.val(); 
    noteField.val(""); 

    /* Send note data to backend, storing in database with existing data 
    associated with userIdToken */ 
    $.ajax(backendHostUrl + '/notes', { 
     headers: { 
     'Authorization': 'Bearer ' + userIdToken 
     }, 
     method: 'POST', 
     data: JSON.stringify({'message': note}), 
     contentType : 'application/json' 
    }).then(function(){ 
     // Refresh notebook display. 
     fetchNotes(); 
    }); 

    }); 
    // [END saveNoteBtn] 

    configureFirebaseLogin(); 
    configureFirebaseLoginWidget(); 

}); 

main.py

# Copyright 2016 Google Inc. 
# 
# Licensed under the Apache License, Version 2.0 (the "License"); 
# you may not use this file except in compliance with the License. 
# You may obtain a copy of the License at 
# 
#  http://www.apache.org/licenses/LICENSE-2.0 
# 
# Unless required by applicable law or agreed to in writing, software 
# distributed under the License is distributed on an "AS IS" BASIS, 
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
# See the License for the specific language governing permissions and 
# limitations under the License. 

# [START app] 
import logging 

from flask import Flask, jsonify, request 
import flask_cors 
from google.appengine.ext import ndb 
import google.auth.transport.requests 
import google.oauth2.id_token 
import requests_toolbelt.adapters.appengine 

# Use the App Engine Requests adapter. This makes sure that Requests uses 
# URLFetch. 
requests_toolbelt.adapters.appengine.monkeypatch() 
HTTP_REQUEST = google.auth.transport.requests.Request() 

app = Flask(__name__) 
flask_cors.CORS(app) 


# [START note] 
class Note(ndb.Model): 
    """NDB model class for a user's note. 

    Key is user id from decrypted token. 
    """ 
    friendly_id = ndb.StringProperty() 
    message = ndb.TextProperty() 
    created = ndb.DateTimeProperty(auto_now_add=True) 
# [END note] 


# [START query_database] 
def query_database(user_id): 
    """Fetches all notes associated with user_id. 

    Notes are ordered them by date created, with most recent note added 
    first. 
    """ 
    ancestor_key = ndb.Key(Note, user_id) 
    query = Note.query(ancestor=ancestor_key).order(-Note.created) 
    notes = query.fetch() 

    note_messages = [] 

    for note in notes: 
     note_messages.append({ 
      'friendly_id': note.friendly_id, 
      'message': note.message, 
      'created': note.created 
     }) 

    return note_messages 
# [END query_database] 


# [START list_notes] 
@app.route('/notes', methods=['GET']) 
def list_notes(): 
    """Returns a list of notes added by the current Firebase user.""" 

    # Verify Firebase auth. 
    # [START verify_token] 
    id_token = request.headers['Authorization'].split(' ').pop() 
    claims = google.oauth2.id_token.verify_firebase_token(
     id_token, HTTP_REQUEST) 
    if not claims: 
     return 'Unauthorized', 401 
    # [END verify_token] 

    notes = query_database(claims['sub']) 

    return jsonify(notes) 
# [END list_notes] 


# [START add_note] 
@app.route('/notes', methods=['POST', 'PUT']) 
def add_note(): 
    """ 
    Adds a note to the user's notebook. The request should be in this format: 

     { 
      "message": "note message." 
     } 
    """ 

    # Verify Firebase auth. 
    id_token = request.headers['Authorization'].split(' ').pop() 
    claims = google.oauth2.id_token.verify_firebase_token(
     id_token, HTTP_REQUEST) 
    if not claims: 
     return 'Unauthorized', 401 

    # [START create_entity] 


    data = request.get_json() 

    # Populates note properties according to the model, 
    # with the user ID as the key name. 
    note = Note(
     parent=ndb.Key(Note, claims['sub']), 
     message=data['message']) 

    # Some providers do not provide one of these so either can be used. 
    note.friendly_id = claims.get('name', claims.get('email', 'Unknown')) 
    # [END create_entity] 

    # Stores note in database. 
    note.put() 

    return 'OK', 200 
# [END add_note] 


@app.errorhandler(500) 
def server_error(e): 
    # Log the error and stacktrace. 
    logging.exception('An error occurred during a request.') 
    return 'An internal error occurred.', 500 
# [END app] 
+0

.py文件中的CORS標頭在哪裏? – mplungjan

+0

我不確定這些是什麼?我需要包括這個嗎?這是谷歌自己的代碼,所以不知道爲什麼它不起作用。 – jb2003

沙发
0
1

我已經試過the tutorial自己,我的一切工作正常,所以我想你可能會跳過一些步驟,或者你有一些錯誤的配置。

唯一明顯的區別我你的榜樣和我之間看,有以下幾種,所以你可以嘗試對其進行修改,以看到您的問題是否得到解決:

  • 我看到一些import error在我的代碼,所以我將這一行werkzeug==0.12.2添加到backend/requirements.txt文件中,該文件包含將要安裝的庫。 werzeug庫的最新版本已將一些依賴關係移至嵌套文件夾,這是爲什麼某些導入失敗的原因(您可以閱讀更多here)。然後,刪除lib文件夾並重新運行該命令以安裝庫pip install -r requirements.txt -t lib。在進行此修改之前,我遇到了與您的問題相同的問題,在我的應用程序中單擊保存按鈕時沒有發生任何事情,但在更改後,它工作正常。
  • 我的frontend/main.js文件中的config變量有一些您已刪除的其他字段。我有以下的參數this guide,並要我的火力地堡控制檯,點擊全面添加火力地堡到你的Web應用程序按鈕,如下複製內容:

config變量frontend/main.js

var config = { 
    apiKey: "<API_KEY>", 
    authDomain: "<PROJECT_ID>.firebaseapp.com", 
    databaseURL: "https://<PROJECT_ID>.firebaseio.com", 
    projectId: "<PROJECT_ID>", 
    storageBucket: "<PROJECT_ID>.appspot.com", 
    messagingSenderId: "<SOME_ID>" 
    }; 

至於其他方面,一切看起來都很好,只是我剛剛嘗試過使用firebase.auth.GoogleAuthProvider.PROVIDER_ID,而我已經刪除了其餘所有內容。我也在運行生產中的應用程序(App Engine標準版),而不是使用本地的開發服務器。我看了一下我的CORS配置過了,我沒有什麼特別的,只有幾行,你已經在你的代碼:

app = Flask(__name__) 
flask_cors.CORS(app) 

你應該嘗試的情侶我提供建議,並與回來有關錯誤的更多信息,如果它不斷出現。

0
votes
answers
57 views
+10

在應用程序引擎項目中創建文件

-2

我想爲每個擁有用戶標識的用戶創建json文件。例如數據文件夾中的123456.json。當我剛剛在簡單的測試文件試試這個沒有燒瓶服務器工作原理:在應用程序引擎項目中創建文件

with open('data/3456789.json', "w+") as f: 
    print("test") 

,但是當我在燒瓶服務器調用它的應用程序引擎創建我收到錯誤No such file or directory: 'data/3456789.json' 這就是我main.py看起來像:

import os, sys 
from flask import Flask 
app = Flask(__name__) 

@app.route('/webhook', methods=['GET']) 
def createFile(): 
    with open('data/3456789.json', "w+") as f: 
    print("test") 
return "Welcome" 

if __name__ == '__main__': 
    port = int(os.getenv('PORT', 5000)) 
    print("Starting app on port %d" % port) 
    app.run(debug=False, port=port, host='0.0.0.0') 

main.py wokrs完美在我自己的電腦。沒有任何錯誤。任何想法?

沙发
0
1

應用程序引擎不會讓您部署的應用程序寫入文件系統。這是應用引擎沙箱的一部分。

但是,您可以從文件系統讀取數據。如果您可以在個人電腦上創建json文件,則可以將它們與您的應用程序一起部署,並且您的應用程序將能夠讀取這些文件。

+0

是的,你是對的。謝謝 :) – MRustamzade