gpt4 book ai didi

json - 在erlang中解析从http返回的json

转载 作者:行者123 更新时间:2023-12-02 06:37:55 29 4
gpt4 key购买 nike

我用这段代码测试:

get_fee(Transaction,SourceNumber,Amount, Currency) ->
Url = lists:concat(["http://localhost/test.php","?transaction=", Transaction, "&saccount=", SourceNumber,Amount,"&currency=",Currency]),
inets:start(),
{Flag, Response} = http:request(get, {Url, []}, [], []),
case Flag of
ok ->
{ { _, ReturnCode, _ }, _, Body } = Response,

if ReturnCode =:= 200 ->
{ok,{_,[{_,Code},{_,Permission},{_,Payer},{_,Payee}]}} = json:decode_string(Body),
case Permission of true ->
if Code =:= 200 ->
{ok,{Code, Payer, Payee}};
Code =:= 204 ->
{nok,{Code, not_found}};
true ->
{nok,{Code, parameter_error}}
end;
false ->
{nok,{Code, parameter_error}}
end;
true->
{error, http_error}
end;
error ->
case Response of
nxdomain -> {error, dns_error};
_ -> {error, network_error}

end
end.

来自 http 的响应是:{"code":200,"permission":true,"fee_payer":0,"fee_payee":19}

但现在我想做同样的事情,但是在这种情况下 http 的返回例如是:

{"CIN":"08321224","Name":21}

所以在这种情况下我只有 CIN 和 Name

我试着改变以前的

get_fee(Num) ->
Url = lists:concat(["http://localhost/GTW/Operation.php","?ACCOUNT_NUM=", Num]),




inets:start(),
{Flag, Response} = http:request(get, {Url, []}, [], []),
case Flag of
ok ->
{ { _, ReturnCode, _ }, _, Body } = Response,
%% for debug
io:format("~p~n",[ReturnCode]),
if ReturnCode =:= "08321224" ->
{ok,{_,[{_,CIN},{_,Name}]}} = json:decode_string(Body),
case Name of 21 ->
io:format(CIN),
io:format(Name),
if CIN =:= "08321224"->
{ok,{CIN, Name}};
CIN =:= 204 ->
{nok,{CIN, not_found}};
true ->
{nok,{CIN, parameter_error}}
end;
false ->
{nok,{CIN, parameter_error}}
end;
true->
{error, http_error}
end;
error ->
case Response of
nxdomain -> {error, dns_error};
_ -> {error, network_error}
%% for debug
%%io:format("pass2~n ~p~n",[Response]),
end
end.

但它显示:

test:get_fee("0001").
200
{error,http_error}

最佳答案

所以我会挑剔这里的风格,因为如果你遵循 Erlang 的语义思想,你会过得更好:

get_fee(Num) ->
Url = lists:concat(["http://localhost/GTW/Operation.php","?ACCOUNT_NUM=", Num]),
inets:start(),

这是开始 inets 的错误位置。它应该在这个函数之外启动,因为你只需要做这个。

{Flag, Response} = http:request(get, {Url, []}, [], []),

这部分最好用模式匹配编码。 FlagResponse的区分可以直接用简单的匹配解码。写,

case http:request(get, {Url, []}, [], []) of
{ok, {{_, 200, _}, _, Body}} ->
{ok, R} = json:decode_string(Body),
get_fee_decode_(get_cin(R), get_name(R));
{error, Reason} -> {error, Reason}
end.

我建议不要将 {error, nxdomain} 更改为 {error, dns_error} 因为 nxdomain 完美在任何情况下都对这种情况进行编码。只需将错误元组传递给调用者并让他处理即可。

get_fee_decode_("08321224" = CIN, 21 = Name) -> {ok, {CIN, Name}};
get_fee_decode_("204" = CIN, 21) -> {nok, {CIN, not_found}};
get_fee_decode_(CIN, _Name) -> {nok, {CIN, parameter_error}};

像这样引入一个新函数来处理代码库的内部部分。并将匹配提升到顶层。从长远来看,这有助于将代码解耦为函数。

请注意,在 JSON 结构中,“对象”没有顺序,因此您不能假设该结构是

{"code":200,"permission":true,"fee_payer":0,"fee_payee":19}

但根据 JSON,解码不必保留此结构。所以一个有效的解码可能是:

[{"fee_payee", 19}, {"fee_payer", 0}, {"permission", true}, {"code", 200}]

这将无法在您的代码中匹配,并且您稍后会为自己设置一些讨厌的错误。

你想要的是:

get_fee_payer(PL) -> proplists:get_value("fee_payer", PL).

另一件与您的编程风格相关的问题是您隐藏了错误信息案例。在 Erlang 中,您通常可以只处理代码中的“快乐路径”而无需处理所有错误,直到您知道代码库中存在何种错误。然后您可以开始慢慢添加错误处理。如果可以避免,防御性编程不是您应该做的事情。

关于json - 在erlang中解析从http返回的json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13958059/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com