dongxing4805 2017-12-29 20:42
浏览 74
已采纳

GoLang WebServer在Json Response上发送对param结构的描述

So here is the deal : I have been working on a huge system (PHP) for a couple years, and now, I decided to give up part of heavy jobs for golang scripts.

So far, I replicated a few php scripts to a go version. Then, I am able to benchmark which option is better ( ok, I know go is faster, but I need curl or sockets to comunication, so, I have to check if it is still worth ) .

One of the scripts just generate a random code, check if this new code is already in use ( on mysql db ), if not, record the new code and return it, if is already in use, just recursive call the function again until find an exclusive code. pretty simple one.

I already had this code generator in php, so, wrote new one in go to be called as http/post with json params. Using linux terminal, I call it as

curl -H [headers] -d [jsondata] [host]

and I get back a pretty simple json

{"locator" : "XXXXXX"}

After, I wrote a simple php script to call the scripts and check how long each took to complete, something like :

<?php
public function indexAction()
    {
    $phpTime = $endPHP = $startPHP =
    $goTime = $endGO = $startGO = 0;

// my standard function already in use


    ob_start();

    $startPHP = microtime(true);
    $MyCodeLocator =  $this->container->get('MyCodeLocator')->Generate(22, 5);
    $endPHP = microtime(true);

    ob_end_clean();


    sleep(1);
    // Lets call using curl
    $data = array("comon" => "22", "lenght" => "5");
    $data_string = json_encode($data);

    ob_start();
    $startGO = microtime(true);



    $ch = curl_init('http://localhost:8888/dev/fibootkt/MyCodeGenerator');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data_string))
    );

    $result = curl_exec($ch);
    curl_close($ch);
    $endGO = microtime(true);
    ob_end_clean();

    $result_rr = json_decode($result);

    // tst just echo the variable in a nice way, second parameter means no kill execution
    tst($result, 1); // HERE IS MY PROBLEM, please read below
    tst($result_rr, 1); // IT SHOW NULL

    sleep(1);

// just to have params for comparision, always try by shell script
    ob_start();
    $startShell = microtime(true);;

    $exec =  "curl -H \"Content-Type: application/json\" -d '{\"comon\":\"22\"}' http://localhost:8888/dev/fibootkt/MyCodeGenerator";
    $output = shell_exec($exec);
    $endShell  = microtime(true);
    ob_end_clean();

    tst(json_decode($output),1); // here show a stdclass with correct value
    tst($output,1); // here shows a json typed string ready to be converted

    // and here it is just for show the execution time ...
    $phpTime = $endPHP - $startPHP;
    $goTime = $endGO - $startGO ;
    $shellTime = $endShell - $startShell;

    tst("php " . $phpTime, 1);
    tst("curl ". $goTime, 1);
    tst("shell " . $shellTime, 1);

And I get the results from GO : By Shell Script :

{"locator" : "DPEWX22"} 

So, this one is pretty and easy decode to a stdobj.

But, using curl, the operation is faster ! So, I want to use it. But, the curl request responds something like :

{"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"}
{"locator":"DPEWX22"}

And when I try to decode it, I get a null as result !!!

CodeLocatorParams the struct type I use in go to get the post params, as show below

so, here is my question : Why GO is returning this ? how to avoid it.

I have another similar go script which take no params and responds a similar json ( but in this case, a qrcode image path ) and it works fine !

My go function:

type CodeLocatorParams struct {
    Comon string `json:"comon"`
    Lenght int  `json:"lenght"`
}

func Generate(w http.ResponseWriter, r *http.Request) {


    data, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
    if err != nil {
        fmt.Println(err)
        panic(err)

    }
    if err := r.Body.Close(); err != nil {
        panic(err)
    }

// retrieve post data  and set it to params which is CodeLocatorParams type
    var params CodeLocatorParams
    if err := json.Unmarshal(data, &params ); err != nil {
        w.Header().Set("Content-Type", "application/json; charset=UTF-8")
        w.WriteHeader(422) // unprocessable entity
        if err := json.NewEncoder(w).Encode(err); err != nil {
            fmt.Println(err)
            panic(err)
        }
    }





    var result struct{
        Locator string `json:"locator"`
    }
// here actually comes the func that generates random code and return it as string, but for now, just set it static
    result.Locator = "DPEWX22"

    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    json.NewEncoder(w).Encode(result)


}
  • 写回答

1条回答 默认 最新

  • douhong1703 2017-12-29 21:19
    关注

    There is an error parsing the incoming JSON. This error is written to the response as {"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"}. The handler continues to execute and writes the normal response {"locator":"DPEWX22"}.

    Here's how what to fix:

    • After writing error response, return from the handler.
    • The input JSON has lenght as a string value. Either change the struct field from int to string or modify the input to pass an integer.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题