2017-12-29 37 views
0

これは取引です:私は巨大なシステム(PHP)を2年間働いていましたが、今はgolangスクリプトの重い仕事の一部を放棄することにしました。GoLang WebServerはJsonのレスポンスでparamの構造体の説明を送信します

これまでのところ、いくつかのPHPスクリプトをgoバージョンに複製しました。それでは、どのオプションが良いかをベンチマークすることができました。(確かに、goは速いと知っていますが、カールやソケットをcomunicationする必要があるので、まだ価値があるかどうかチェックしなければなりません)。

スクリプトの1つでは、ランダムコードを生成するだけで、この新しいコードが既に使用されているかどうかをチェックします(mysql dbの場合)。新しいコードを記録して返します。排他的なコードを見つけるまで機能します。かなりシンプルなもの。

私はすでにPHPでこのコードジェネレータを持っていたので、json paramsでhttp/postとして呼び出すために新しいコードを書きました。 Linuxターミナルを使用して、私は

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

としてそれを呼び出すと、私はスクリプトを呼び出すと、それぞれのにかかった時間をチェックするために、単純なPHPスクリプトを書いた後、私は戻って非常に単純なJSON

{"locator" : "XXXXXX"} 

を取得、完全な何か:

<?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からの結果を得る:シェルスクリプトによって :

{"locator" : "DPEWX22"} 

だから、これはかなり簡単にstdobjにデコードします。

ただし、カールを使用すると操作が速くなります。だから私はそれを使いたい。 しかし、カール要求のようなものに応答します。

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

を、私はそれを解読しようとすると、私は結果としてnullを取得します!!!

CodeLocatorParamsので

下記のショーとして、私はポストのparamsを取得するには、外出先での使用構造体の種類、ここで私の質問は:GOはこれを返しているのはなぜ?それを避ける方法。

私はparamsを取らず、同様のjson(しかし、この場合はqrcodeイメージパス)に応答する別の同様の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) 


} 

答えて

1

の着信JSONの構文解析エラーがあります。このエラーは応答に{"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"}として書き込まれます。ハンドラは実行を継続し、通常の応答{"locator":"DPEWX22"}を書き込みます。

はここで何を修正する方法は次のとおりです。

  • エラー応答を書き込んだ後、ハンドラから復帰します。
  • 入力JSONの長さは文字列値です。 structフィールドをintからstringに変更するか、入力を変更して整数を渡します。
+0

yeap! lenghtを整数として使うと問題は解決しました!それはとてもシンプルだったと信じています!ありがとうございます@cerise! –

+0

私は自分自身が決してエラー警告ではないことを認識したことはありません。私はそれが何らかのヘッダであると思った。 –

+0

@DiegoFaveroこれは 'json.NewEncoder(w).Encode(err)'の出力です。 JSONとしてエラーをエンコードすることはめったに望まれません。より良い選択肢は、err.Error()をエンコードすることです。これは実装の詳細がクライアントに漏れるため、理想的ではありません。 JSONを解析する際の一般的なエラーがおそらく最良の選択です。 –

関連する問題