我们如何在Java中获取不同appId和命名空间的Google App Engine安全URL密钥?

时间:2017-08-14 17:39:44

标签: google-app-engine google-cloud-datastore

当我只需要为没有命名空间的应用程序执行此操作时,我可以使用以下代码:

overlap

不幸的是,当我需要为不同的appId或命名空间做这件事时,我找不到用Java做任何事情的方法。

在python中,我可以使用以下代码:

var word: String!
var translation: String!
var exOne: String!
var exTwo: String!
var key: String!

// handle swipe icons and actions
 func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? {
    let edit = UITableViewRowAction(style: .normal, title: "Edit") { action, index in
        self.word = self.words[editActionsForRowAt.row].word
        self.translation = self.words[editActionsForRowAt.row].translation
        self.exOne = self.words[editActionsForRowAt.row].exOne
        self.exTwo = self.words[editActionsForRowAt.row].exTwo
        self.key = self.words[editActionsForRowAt.row].keyRandom
        self.performSegue(withIdentifier: "edit", sender: self)
    }
    edit.backgroundColor = UIColor.darkGray
...

}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

var editContoller: EditController!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "edit" {
        editContoller = segue.destination as? EditController
        editContoller.wo = word
        editContoller.tran = translation
        editContoller.eO = exOne
        editContoller.eT = exTwo
        editContoller.key = key
    }
}

但在Java中,这似乎并不可用。

我对如何做到这一点有任何想法?

2 个答案:

答案 0 :(得分:1)

App Engine SDK确实试图禁止这一点,因为缺少可以处理应用程序ID和名称空间的公共类/方法。即使在python中,_app关键字参数的下划线前缀也不鼓励这样做。这可能是因为App Engine应用程序在他们的项目中得到了很好的控制。

可以使用反射来解决这些障碍,但仅适用于标准Java 8运行时(目前处于测试阶段)。标准Java 7运行时禁止reflecting non-accessible methods。 (如果你正在使用App Engine Flex我怀疑你也会好起来的,虽然我还没有测试过。)

如果您已经在使用Java 8或愿意切换,我可以使用以下内容为任意应用程序ID /名称空间创建密钥:

Key createKey(String appId, String namespace, String kind, long id) {
  try {
    Class<?> appNsClazz = Class.forName("com.google.appengine.api.datastore.AppIdNamespace");
    Constructor<?> constructor = appNsClazz.getConstructor(String.class, String.class);
    constructor.setAccessible(true);

    Constructor<Key> keyFactory = Key.class.getDeclaredConstructor(String.class, 
      Key.class, long.class, String.class, appNsClazz);
    keyFactory.setAccessible(true);

    Object appNs = constructor.newInstance(appId, namespace);
    return keyFactory.newInstance(kind, /* parent key */ null, id, /* name */ null, appNs);
  } catch (ClassNotFoundException | NoSuchMethodException | 
           InvocationTargetException | InstantiationException | 
           IllegalAccessException e) {
    throw new RuntimeException(e);
  }
}

如果您将经常运行此代码,最好缓存构造函数实例,并尽可能缓存appNs实例,以避免反射的性能开销。

请注意,此代码无法在标准Java 7运行时上运行。

答案 1 :(得分:0)

最后,我能够使用以下代码(查看KeyFactory如何在内部执行):

{
    "displayWonder": {
        "Source": [
            "    def displayWonder(self):",
            "        return \"Hello \" + str(self.displayGreeting())"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "displayGreeting": {
        "Source": [
            "    def displayGreeting(self):",
            "        string = \"Greetings \" + self.myName",
            "        return string"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "myStatic": {
        "Source": [
            "    @staticmethod",
            "    def myStatic():",
            "        return \"I am static\""
        ],
        "Args": [],
        "Callees": []
    },
    "displayHello": {
        "Source": [
            "    def displayHello(self):",
            "        return \"Hello \" + self.myName"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "__init__": {
        "Source": [
            "    def __init__(self):",
            "        self.myName = 'Wonder?'"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "main": {
        "Source": [
            "def main():",
            "    hello = Hello(\"Wonderful!!!\")",
            "    # name = unicode(raw_input(\"Enter name: \"), 'utf8')",
            "    # print(\"User specified:\", name)",
            "    print(hello.displayGreeting())"
        ],
        "Args": [],
        "Callees": []
    }
}