不应命名Cloud Endpoint参数

时间:2013-07-03 17:29:22

标签: java javascript google-app-engine google-api google-cloud-endpoints

我想从JS应用程序向我的Google App发送HashMap<String, String>。我创建了一个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 个答案:

答案 0 :(得分:7)

Google Cloud Enpoints documentation说:

  

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

基本上,据我所知,当您添加@Named注释时,参数将包含在请求网址的末尾:

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

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

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

为了使用Google API Client Library for JavaScript在HTTP正文中发送参数,您只需将该参数包含在JSON-RPC请求中名为resource的对象中,如下所示:

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

API客户端会自动在网址中发送param1,在POST数据中自动发送param2 ...

Google API客户端库for JavaScript文档的this section详细说明了这一点。

答案 1 :(得分:2)

使用HashMap会将所有参数传递给Api方法,我建议您使用 HaspMap<String,Object> 作为param2地图类型,  然后这通知我们在这个hashmap中我们可以将param2作为hashmap的键。然后我们可以将param键的值类型转换为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());

        }

答案 2 :(得分:1)

This doc中的示例显示了使用的注释与代码显示的顺序不同。

  

公共资源获取(@Named(&#34; id&#34;)@Nullable int id){...}

所以根据这个,你的

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

应该成为

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

我测试了两种方式 - 只有后者似乎适合我。

答案 3 :(得分:1)

从我提出这个问题之日起,我发现“另一种方式”使用Google Cloud Endpoints。通过遵循文档,我们可以很容易地弄清楚如何从JavaScript脚本中发送HashMap(实际上是Object)。

定义Endpoints/annotations#named

  

对于传递给服务器端方法的所有非实体类型参数,需要@ strong注释。此批注指示在此处注入的请求中的参数名称。 未使用@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必须是第一个)。