5

我想HashMap<String, String>从 JS 应用程序发送一个到我的 Google 应用程序。我创建了一个HashMapContainer类,例如:Cloud Endpoints Collection Parameter

Endpoint 方法的定义如下:

public Entity myMethod(
        @Named('param1') String param1, 
        @Nullable @Named('param2') HashMapContainer param2) {
    //...
}

当我运行 API 生成时,会发生此错误:

com.google.api.server.spi.config.validation.ApiConfigInvalidException: 
    Resource type 'class com.mason.server.entity.HashMapContainer' 
    in method 'endpoint.myMethod' should not be named.

因此,我删除了@Named注释。API 已生成,但很明显,我没有收到 JS 应用程序发送的参数。我的 JavaScript 是这样的:

function doTransaction() {
    var req = gapi.client.myApi.endpoint.myMethod({
        'param1': 'FOO',
        'param2': {
            'value1':'foofoo',
            'value2':'barbar',
            'value3':'foobar'
        }
    });
    req.execute(function(data) {
        console.log(data);
    });
}

param2如果我不允许使用@Named注释,我怎么能得到?
也许我的 JavaScript 错了?

4

4 回答 4

7

Google Cloud Enpoints文档说:

@Named:此注解表示在此处注入的请求中的参数名称。未使用 @Named 注释的参数被注入整个请求对象。

基本上,据我了解,当您添加@Named注释时,参数将包含在请求 URL 的末尾:

http://end_point_url?parameter1=xxx&parameter2=yyy

显然,支持@Named注解的参数类型只有少数(我认为是 int、long、String、Boolean 及其对应的数组),因为您不能将整个 hashmap 附加到请求 URL!

另一方面,如果您不使用@Named,则该参数将包含(注入)在 POST 数据中。

为了使用适用于 JavaScript 的 Google APIs 客户端库在 HTTP 正文中发送参数,您只需将该参数包含resource在 JSON-RPC 请求内部调用的对象中,如下所示:

var req = gapi.client.myApi.endpoint.myMethod({
    'param1': 'FOO',
    'resource': {
        'param2': {
            'value1':'foofoo',
            'value2':'barbar',
            'value3':'foobar'
        }
    }
});

API 客户端将自动发送param1URL 和param2POST 数据...

这在 Google APIs Client Library for JavaScript 文档的本节中有详细说明。

于 2013-07-03T20:57:55.887 回答
2

使用 HashMap 会将所有参数传递给 Api 方法,我建议您将HaspMap<String,Object>其用作 param2 映射类型,然后这会通知我们在此哈希映射中我们可以将 param2 作为哈希映射的键。然后我们可以将参数键的值类型转换为 HashMap,然后我们可以像最初传递的正常初始 hashMap 一样循环遍历它。

HashMap <String,String> mapR = (HashMap <String,String>) param2.get("param2");

        for(Map.Entry<String,String> x:mapR.entrySet()){
            log.log(Level.INFO,x.getKey()+","+x.getVaue());

        }
于 2016-07-18T15:39:58.990 回答
1

本文档中的示例显示了使用的注释,其顺序与您的代码显示的顺序不同。

公共资源获取(@Named(“id”)@Nullable int id){…}

所以根据这个,你的

@Nullable @Named('param2') HashMapContainer param2) {

应该成为

@Named('param2') @Nullable HashMapContainer param2) {

我对它进行了两种方式的测试 - 只有后者似乎对我有用。

于 2016-05-08T02:28:31.203 回答
1

从我提出这个问题的那天起,我就找到了使用Google Cloud Endpoints的“另一种方式”。通过遵循文档,很容易弄清楚我们如何从 JavaScript 脚本发送 HashMap(实际上是对象)。

定义端点/注释#named

传递给服务器端方法的所有非实体类型参数都需要 @Named 注释。此注解指示在此处注入的请求中的参数名称。未使用 @Named 注释的参数将被注入整个请求对象


JavaScript

我们通过 REST API 发送一个 JS 对象。

function doSomething() {
    var req = gapi.client.myApi.myMethod({
        'param1': 'FOO',
        'value1': 'foofoo',
        'value2': 'barbar',
        'value3': 'foobar'
    });
    req.execute(function(data) {
        console.log(data);
    });
}


Java API

我们在 Java Map 中接收所有未注释的参数。它们在 HTTP 请求正文中发送(如文档中的描述)。

public Entity myMethod(
    @Named('param1') String param1, 
    Map<String, Object> param2) {

    System.out.println(param1); // FOO
    System.out.println(String.valueOf(param2.get("value1"))); // foofoo
    System.out.println(String.valueOf(param2.get("value2"))); // barbar
    System.out.println(String.valueOf(param2.get("value3"))); // foobar

    //...
}

注意名称“param2”对于客户端无关紧要,它可以命名为“resources”。

此示例不是最佳实践,而是将请求中的参数和数据发送到正文中的最简单方法。您可以使用自己的类(而不是 Java Map 接口)对其进行改进,并在需要时添加@ApiTransformer。如果您使用实体作为参数,请确保注释顺序(@named必须是第一个)。

于 2016-05-08T12:15:20.687 回答