jjzjj

php - GoLang Web 服务器在 Json 响应中发送参数结构的描述

coder 2024-07-07 原文

事情是这样的:我已经在大型系统 (PHP) 上工作了几年,现在,我决定放弃部分繁重的工作,转而使用 golang 脚本。

到目前为止,我将一些 php 脚本复制到了一个 go 版本中。然后,我能够对哪个选项更好进行基准测试(好的,我知道 go 更快,但我需要 curl 或 sockets 进行通信,所以,我必须检查它是否仍然值得)。

其中一个脚本只是生成一个随机代码,检查这个新代码是否已经被使用(在mysql db上),如果没有,记录新代码并返回它,如果已经被使用,就递归调用函数再次直到找到独占代码。非常简单。

我已经在 php 中有了这个代码生成器,所以,在 go 中写了一个新的,被称为带有 json 参数的 http/post。 使用 linux 终端,我称之为

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

然后我得到一个非常简单的 json

{"locator" : "XXXXXX"}

之后,我编写了一个简单的 php 脚本来调用脚本并检查每个脚本完成需要多长时间,例如:

<?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);

然后我从 GO 得到结果: 通过 Shell 脚本:

{"locator" : "DPEWX22"} 

因此,这个非常容易解码为 stdobj。

但是,使用 curl,操作更快!所以,我想使用它。 但是,curl 请求响应如下:

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

当我尝试对其进行解码时,结果为空!!!

CodeLocatorParams 是我在 go 中用来获取 post 参数的结构类型,如下所示

所以,这是我的问题:为什么 GO 返回这个?如何避免。

我有另一个类似的 go 脚本,它不带参数并响应类似的 json(但在这种情况下,是一个二维码图像路径)并且它工作正常!

我的 go 函数:

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)


}

最佳答案

解析传入的 JSON 时出错。此错误以 {"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"} 形式写入响应。处理程序继续执行并写入正常响应 {"locator":"DPEWX22"}

修复方法如下:

  • 写入错误响应后,从处理程序返回。
  • 输入 JSON 的长度为字符串值。要么将结构字段从 int 更改为字符串,要么修改输入以传递整数。

关于php - GoLang Web 服务器在 Json 响应中发送参数结构的描述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48028207/

有关php - GoLang Web 服务器在 Json 响应中发送参数结构的描述的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  5. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  6. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  7. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  8. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  9. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  10. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

随机推荐